首页 > 解决方案 > 是否调用 pytest_runtest_teardown 来跳过测试,而 pytest_runtest_setup 不是?

问题描述

我有一个实现以下钩子的插件:

def pytest_runtest_setup(item):
    item.config.bla = Bla()

def pytest_runtest_teardown(item):
    item.config.bla.do_bla()
    item.config.bla = None

一切正常,直到一些测试开始抛出AttributeError: 'NoneType' object has no attribute 'do_bla',事实上,item.config.blaNone

这发生在我标记为的测试中

@pytest.mark.skip(reason='bla bla')
def test_bla():
    pass

我尝试ipdb了设置挂钩 - 但它没有被调用,而拆解是。在拆解时不调用设置进行跳过测试是否有意义?

我可以用我的拆解包装,try, except但我想验证根本原因......

标签: pythonpluginspytestteardown

解决方案


问题似乎是pytest_runtest_setup钩子是由 pytest 本身的几个组件实现的,一个是skipping模块(_pytest/skipping.py)。
实现是这样的:

@hookimpl(tryfirst=True)
def pytest_runtest_setup(item):
    ...
    for skip_info in item.iter_markers(name="skip"):
        item._store[skipped_by_mark_key] = True
        if "reason" in skip_info.kwargs:
            skip(skip_info.kwargs["reason"])
        elif skip_info.args:
            skip(skip_info.args[0])
        else:
            skip("unconditional skip")

例如,如果它找到一个skip标记,它就会引发Skipped()(基本上就是skip这样),只有在执行任何预测试和测试钩子之后才会捕获它。

我不知道这是否是故意的,但您显然必须期待这种行为(在您的情况下,您可以通过捕获AttributeError,正如您所写的那样轻松做到这一点)。


推荐阅读