我正在尝试 py.test,因为它声称对模块和会话装置的支持比 unittest 更好,但我偶然发现了一种奇怪的行为,至少对我来说是这样。
考虑以下代码(不要告诉我它很愚蠢,我知道,这只是复制行为的快速而肮脏的黑客行为)(我在 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
为模块调用一次夹具,并在测试结束时调用一次清理。
然后,如果test_work_dir
存在,我会期望类似于 unittest 的东西,该夹具被调用一次,它失败OSError
,需要它的测试不会运行,清理被调用一次并再次建立世界和平。
但是......这就是我所看到的:
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'
为每个测试调用一次夹具,并且终结器从未调用!
我知道夹具中的异常不是好的策略,但是真正的夹具很复杂,如果我可以依靠每个终结器集的执行直到故障点,我宁愿避免用 try 块填充它们。我不想在失败后去寻找测试工件。此外,当他们需要的所有固定装置都没有到位时,尝试运行测试是没有意义的,而且充其量会使它们变得不稳定。
这是 py.test 在夹具失败的情况下的预期行为吗?
谢谢,加布里埃尔