2013-04-04 10 views
5

にコンテキストマネージャを使用する方法:In python, is there a good idiom for using context managers in setup/teardownpy.test - funcarg /フィクスチャ密接に関連


私は時間/タイムゾーンを修正するためにテストで使用されたコンテキストマネージャを持っています。私はそれをpytest funcarg(またはfixture、私たちは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) 

...しかしそれはちょっと嬉しいです。関連するQ jsbuenoが指摘している点:例外は、例外が発生した場合、コードにオブジェクトの__exit__メソッドを正しく呼び出す手段がないことが問題です。

His answerはメタクラスアプローチを使用します。しかし、これはpytestにはあまり役に立ちません。多くの場合、テストはクラスではなく関数でしかありません。では、これを解決するにはどうすればいいのでしょうか? runtest hooksを含む何か?

答えて

0

現在、フィクスチャでコンテキストマネージャを使用するためのエレガントな方法はありません。テストが失敗した場合は、ファイナライザが実行されます:

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#context-managers)。 '__exit__'は、通常、' with'ブロック(またはこの場合はテスト本体です)で発生した例外に関する値で呼び出されます。 – pfctdayelise

9

2.4以降、py.testyieldスタイルフィクスチャサポートを持っています。その内部に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の変更に対する答えを更新しました。 –

関連する問題