13

密接に関連しています: Pythonでは、セットアップ/ティアダウンでコンテキストマネージャーを使用するための良いイディオムがありますか


時間/タイムゾーンを修正するためにテストで使用されるコンテキストマネージャーがあります。私はそれをpytest funcarg(またはフィクスチャ、pytest2.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__メソッドを適切に呼び出すための準備がコードにないことです。

彼の答えは、メタクラスのアプローチを使用しています。しかし、これは、多くの場合、テストがクラスではなく単なる関数である pytest にはあまり役立ちません。では、これを解決する pytest-y の方法は何でしょうか? runtest フックに関するものはありますか?

4

2 に答える 2

19

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()
于 2015-04-08T06:49:11.530 に答える
1

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

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__()

于 2013-04-04T12:17:22.333 に答える