2

モジュールとセッションフィクスチャのユニットテストよりも優れたサポートを主張しているpy.testを試していましたが、少なくとも私にとっては奇妙な動作に遭遇しました。

次のコードを考えてみてください(馬鹿げているとは言わないでください、私はそれを知っています、それは動作を複製するための簡単で汚いハックです)(私はWindows 7のPython 2.7.5 x86で実行しています) import os import shutil import pytest

test_work_dir = 'test-work-dir'
tmp = os.environ['tmp']
count = 0

@pytest.fixture(scope='module')
def work_path(request):
    global count
    count += 1
    print('test: ' + str(count))
    test_work_path = os.path.join(tmp, test_work_dir)

    def cleanup():
        print('cleanup: ' + str(count))
        if os.path.isdir(test_work_path):
            shutil.rmtree(test_work_path)
    request.addfinalizer(cleanup)
    os.makedirs(test_work_path)
    return test_work_path

def test_1(work_path):
    assert os.path.isdir(work_path)
def test_2(work_path):
    assert os.path.isdir(work_path)
def test_3(work_path):
    assert os.path.isdir(work_path)

if __name__ == "__main__":
    pytest.main(['-s', '-v', __file__])

存在しない場合test_work_dirは、期待される動作を取得します。

platform win32 -- Python 2.7.5 -- pytest-2.3.5 -- C:\Programs\Python\27-envs\common\Scripts\python.exe
collecting ... collected 4 items

py_test.py: [doctest] PASSED
py_test.py:34: test_1 test: 1
cleanup: 1
PASSED
py_test.py:38: test_2 PASSED
py_test.py:42: test_3 PASSEDcleanup: 1

フィクスチャはモジュールに対して 1 回呼び出され、クリーンアップはテストの最後に 1 回呼び出されます。

次に、test_work_dir存在する場合、 unittest に似たものが期待されます。そのフィクスチャは1回呼び出され、 で失敗しOSError、必要なテストは実行されず、クリーンアップが1回呼び出され、世界の平和が再び確立されます。

しかし...ここに私が見るものがあります:

py_test.py: [doctest] PASSED
py_test.py:34: test_1 test: 1
ERROR
py_test.py:38: test_2 test: 2
ERROR
py_test.py:42: test_3 test: 3
ERROR

フィクスチャの失敗にもかかわらず、すべてのテストが実行されますが、本来あるべきフィクスチャはscope='module'テストごとに 1 回呼び出され、ファイナライザーは呼び出されません!

フィクスチャの例外は適切なポリシーではないことはわかっていますが、実際のフィクスチャは複雑であり、障害が発生するまで各ファイナライザー セットの実行を期待できる場合は、try ブロックで満たすことは避けたいと思います。失敗した後にテスト成果物を探しに行きたくありません。さらに、必要なすべてのフィクスチャが配置されていないときにテストを実行しようとしても意味がなく、せいぜい不安定になる可能性があります。

これは、フィクスチャで障害が発生した場合の py.test の意図した動作ですか?

ありがとう、ガブリエレ

4

1 に答える 1

2

ここに 3 つの問題があります。

  • 元に戻したいアクションを実行した後、ファイナライザーを登録する必要があります。したがって、最初に makedirs() を呼び出してから、ファイナライザーを登録します。通常、ティアダウン コードは何かが正常に作成された場合にのみ実行できるため、これはフィクスチャの一般的な問題です。

  • pytest-2.3.5 には、フィクスチャ関数が失敗した場合にファイナライザーを呼び出さないというバグがあります。私はそれを修正しました.2.4.0.dev7(またはそれ以上)のバージョンをpip install -i http://pypi.testrun.org -U pytest. これにより、フィクスチャ関数が部分的に失敗した場合でも、フィクスチャ ファイナライザが確実に呼び出されます。実際、これが以前に現れなかったのは少し驚くべきことですが、私を含む人々は通常、具体的に何が起こっているのかに飛び込むのではなく、先に進んで備品を修正するだけだと思います. ここに投稿してくれてありがとう!

  • モジュールスコープのフィクスチャ関数が失敗した場合、そのフィクスチャを必要とする次のテストは、断続的な失敗であった可能性があるため、フィクスチャ関数の実行を再度トリガーします。pytest が指定されたスコープの失敗を記憶し、実行を再試行しないのは理にかなっています。そう思う場合は、このスタックオーバーフロー ディスカッションにリンクして問題を開いてください。

ありがとう、ホルガー

于 2013-07-17T08:35:12.177 に答える