2013-04-04 15 views
5

निकट से संबंधित में एक संदर्भ प्रबंधक का उपयोग करने:In python, is there a good idiom for using context managers in setup/teardownpy.test - कैसे एक funcarg/स्थिरता


मैं एक संदर्भ प्रबंधक उस समय/समय क्षेत्र तय करने के लिए परीक्षण में इस्तेमाल किया जाता है। मैं इसे एक सबसे मजेदार मकसद में रखना चाहता हूं (या स्थिरता, हम pytest 2.2.3 का उपयोग कर रहे हैं लेकिन मैं पीछे की ओर अनुवाद कर सकता हूं)। मैं तो बस ऐसा कर सकता है:

def pytest_funcarg__fixedTimezone(request): 
    # fix timezone to match Qld, no DST to worry about and matches all 
    # Eastern states in winter. 
    fixedTime = offsetTime.DisplacedRealTime(tz=' Australia/Brisbane') 

    def setup(): 
     fixedTime.__enter__() 
     return fixedTime 

    def teardown(fixedTime): 
     # this seems rather odd? 
     fixedTime.__exit__(None, None, None) 

... लेकिन यह एक बिट को भावुक है। संबंधित प्रश्न jsbueno अंक: समस्या यह है कि अपवाद होने पर आपके कोड में ऑब्जेक्ट की __exit__ विधि को ठीक से कॉल करने का कोई प्रावधान नहीं है।

His answer मेटाक्लास दृष्टिकोण का उपयोग करता है। लेकिन यह पाइस्टेस्ट के लिए उपयोगी नहीं है जहां अक्सर परीक्षण केवल कार्य होते हैं, कक्षाओं में नहीं। तो इसे हल करने के लिए सबसे पुराना तरीका क्या होगा? runtest hooks में कुछ शामिल है?

उत्तर

0

मुझे डर है कि वर्तमान में फिक्स्चर में संदर्भ प्रबंधकों का उपयोग करने का कोई शानदार तरीका नहीं है। हालांकि finalizers यदि परीक्षण में विफल रहता है चलेंगे:

import contextlib, pytest 

@contextlib.contextmanager 
def manager(): 
    print 'manager enter' 
    yield 42 
    print 'manager exit' 

@pytest.fixture 
def fix(request): 
    m = manager() 
    request.addfinalizer(lambda: m.__exit__(None, None, None)) 
    return m.__enter__() 

def test_foo(fix): 
    print fix 
    raise Exception('oops') 

आप pytest -s के साथ इस चलाते हैं तो आप देखेंगे कि __exit__() कॉल होता है।

+1

मेरी चिंता यह नहीं है कि '__exit__' नहीं कहा जा सकता है, लेकिन इसे [सही मान] (http://docs.python.org/2/reference/datamodel) से नहीं बुलाया जाएगा .html # संदर्भ प्रबंधकों)। '__exit__' को आम तौर पर 'साथ' ब्लॉक में उठाए गए किसी भी अपवाद से संबंधित मूल्यों के साथ बुलाया जाता है (या इस मामले में यह परीक्षण निकाय होगा)। – pfctdayelise

9

2.4, py.test के बाद yield शैली स्थिरता समर्थन है। हम सीधे with संदर्भ का उपयोग कर सकते हैं।

@pytest.yield_fixture 
def passwd(): 
    with open("/etc/passwd") as f: 
     yield f.readlines() 

3,0 के बाद से, py.test@pytest.yield_fixture उपयोग पदावनत। हम सीधे संदर्भ प्रबंधक के रूप में @pytest.fixture का उपयोग कर सकते हैं।

@pytest.fixture 
def passwd(): 
    with open("/etc/passwd") as f: 
     yield f.readlines() 
+0

मुझे लगता है कि उपज शैली जुड़नार बहिष्कृत हैं? –

+1

@NeilG आपकी टिप्पणी के लिए धन्यवाद। मैंने pytest 3.0 परिवर्तनों के लिए उत्तर अद्यतन किया है। –

संबंधित मुद्दे