我正在尝试py.test,因为它声称比模块测试和会话固定装置更好地支持unittest,但我偶然发现了一种奇怪的行为,至少对我而言。

考虑以下代码(不要告诉我这很愚蠢,我知道,这只是复制行为的一种快速而肮脏的技巧)(我在Windows 7上的Python 2.7.5 x86上运行)
    导入操作系统
    进口壁垒
    导入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


尽管Fixture失败,所有测试仍在运行,对于每个测试,应该调用scope='module'的Fixture一次,而终结器从未调用!

我知道夹具中的例外不是一个好的策略,但是真正的夹具是复杂的,如果我可以依靠每个终结器集的执行直到失败点,我宁愿避免用try块填充它们。失败后,我不想去寻找测试工件。
而且,在并非所有需要的固定装置都就位时尝试运行测试是没有意义的,并且可能会使它们最不稳定。

如果固定装置发生故障,这是py.test的预期行为吗?

谢谢加布里埃

最佳答案

这里的三个问题:


您应该在执行了要撤消的操作之后注册终结器。因此,首先调用makedirs(),然后注册终结器。这是灯具的一个普遍问题,因为通常只有在成功创建某些东西后才能运行拆卸代码
pytest-2.3.5有一个错误,即如果Fixture函数失败,它将不会调用终结器。我已经修复了它,您可以使用pip install -i http://pypi.testrun.org -U pytest安装2.4.0.dev7(或更高版本)版本。它确保即使夹具功能部分失败,也可以调用夹具终结器。实际上,这种情况并没有更早出现,但我认为包括我在内的人们通常只是继续修理设备,而不是专心研究正在发生的事情。因此,感谢您在此处发布!
如果模块范围内的夹具功能失败,则下一个需要该夹具的测试仍将再次触发夹具功能的执行,因为这可能是间歇性故障。有理由认为pytest应该记住给定范围的失败,而不是重试执行。如果您这样认为,请打开一个问题,链接到此stackoverflow讨论。


谢谢,霍尔格

关于python - 夹具故障后py.test 2.3.5不运行终结器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17664702/

10-10 21:22