如何根据 运行 测试结果在模块范围内使用拆卸功能
How to have a teardown function in module scope based on running test result
我想在所有测试通过后清理一些文件。如果失败,请保留它们以供调试。我阅读 https://docs.pytest.org/en/latest/example/simple.html#making-test-result-information-available-in-fixtures 所以我的 conftest.py
中有以下内容:
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
rep = outcome.get_result()
# set a report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)
@pytest.fixture(scope="module", autouse=True)
def teardown(request):
yield
# request.node is an "item" because we use the default
# "function" scope
if request.node.rep_setup.failed:
print("setting up a test failed!", request.node.nodeid)
elif request.node.rep_setup.passed:
#clean up my files
然而,我得到了错误:
AttributeError: 'Module' object has no attribute 'rep_setup'
与文档示例的唯一区别是我的拆解有'scope=module'
。但我必须这样做,因为我想在所有测试通过后清理文件,一些文件被所有测试使用。如果我使用 'function' 级别的默认范围,它将在每个测试用例之后而不是在整个模块之后进行清理。我该如何解决这个问题?
更新:在我有 'hook' 之前,我仍然有 teardown
,即 "module" 级别,它工作正常,这意味着它在所有测试后为我清理了所有文件运行,唯一的问题是无论测试通过与否,它都会为我清理。
如果您在模块范围内,request.node
表示模块,而不是单个测试。如果你只想检查失败的测试,你可以检查会话:
@pytest.fixture(scope="module", autouse=True)
def teardown(request):
yield
if request.session.testsfailed > 0:
print(f"{} test(s) failed!", request.session.testsfailed)
else:
# clean up my files
如果您只对这些感兴趣,我不确定此时请求中是否有任何关于设置失败的信息。
在这种情况下,您可以实现一个文件范围的固定装置,它在设置失败的情况下设置一个标志,并使用它,例如:
SETUP_FAILED = False
@pytest.fixture(autouse=True)
def teardown_test(request):
yield
if request.node.rep_setup.failed:
global SETUP_FAILED
SETUP_FAILED = True
@pytest.fixture(scope="module", autouse=True)
def teardown_module():
global SETUP_FAILED
SETUP_FAILED = False
yield
if SETUP_FAILED:
print("At least one test setup failed!")
else:
# clean up my files
这不太好,也许有人知道更好的解决方案,但它会起作用。
如果需要,您还可以收集有关设置失败的测试的信息。
我想在所有测试通过后清理一些文件。如果失败,请保留它们以供调试。我阅读 https://docs.pytest.org/en/latest/example/simple.html#making-test-result-information-available-in-fixtures 所以我的 conftest.py
中有以下内容:
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
rep = outcome.get_result()
# set a report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)
@pytest.fixture(scope="module", autouse=True)
def teardown(request):
yield
# request.node is an "item" because we use the default
# "function" scope
if request.node.rep_setup.failed:
print("setting up a test failed!", request.node.nodeid)
elif request.node.rep_setup.passed:
#clean up my files
然而,我得到了错误:
AttributeError: 'Module' object has no attribute 'rep_setup'
与文档示例的唯一区别是我的拆解有'scope=module'
。但我必须这样做,因为我想在所有测试通过后清理文件,一些文件被所有测试使用。如果我使用 'function' 级别的默认范围,它将在每个测试用例之后而不是在整个模块之后进行清理。我该如何解决这个问题?
更新:在我有 'hook' 之前,我仍然有 teardown
,即 "module" 级别,它工作正常,这意味着它在所有测试后为我清理了所有文件运行,唯一的问题是无论测试通过与否,它都会为我清理。
如果您在模块范围内,request.node
表示模块,而不是单个测试。如果你只想检查失败的测试,你可以检查会话:
@pytest.fixture(scope="module", autouse=True)
def teardown(request):
yield
if request.session.testsfailed > 0:
print(f"{} test(s) failed!", request.session.testsfailed)
else:
# clean up my files
如果您只对这些感兴趣,我不确定此时请求中是否有任何关于设置失败的信息。
在这种情况下,您可以实现一个文件范围的固定装置,它在设置失败的情况下设置一个标志,并使用它,例如:
SETUP_FAILED = False
@pytest.fixture(autouse=True)
def teardown_test(request):
yield
if request.node.rep_setup.failed:
global SETUP_FAILED
SETUP_FAILED = True
@pytest.fixture(scope="module", autouse=True)
def teardown_module():
global SETUP_FAILED
SETUP_FAILED = False
yield
if SETUP_FAILED:
print("At least one test setup failed!")
else:
# clean up my files
这不太好,也许有人知道更好的解决方案,但它会起作用。 如果需要,您还可以收集有关设置失败的测试的信息。