我正在尝试py.test,因为它声称比模块和会话装置的单元测试更好的支持,但我偶然发现了一个,至少对我而言,奇怪的行为。
考虑以下代码(不要告诉我它是愚蠢的,我知道,它只是一个快速而又脏的黑客来复制行为)(我在Windows 7上运行Python 2.7.5 x86) 进口口 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
为模块调用一次fixture,并在测试结束时调用一次。
然后如果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的预期行为吗?
谢谢,加布里埃尔
答案 0 :(得分:2)
这里有三个问题:
您应该在执行要撤消的操作后注册终结器。所以先调用makedirs()然后注册终结器。这是固定装置的一般问题,因为通常的拆解代码只能在成功创建的情况下运行
pytest-2.3.5有一个错误,如果fixture功能失败,它将不会调用终结器。我刚刚修复了它,您可以使用pip install -i http://pypi.testrun.org -U pytest
安装2.4.0.dev7(或更高版本)版本。它确保即使夹具功能部分失效也会调用夹具终结器。实际上有点令人惊讶的是,这并没有提前出现,但我想人们,包括我在内,通常只是继续修理固定装置,而不是专注于正在发生的事情。所以,谢谢你在这里发帖!
如果模块范围的夹具功能失效,则需要该夹具的下一个测试仍将再次触发夹具功能的执行,因为它可能是间歇性故障。按理说,pytest应该记住给定范围的失败而不是重试执行。如果您这么认为,请打开一个问题,链接到此stackoverflow讨论。
谢谢,holger