我知道可以制作自定义 pytest 结果(制作自定义测试结果),但是我正在努力为通过的测试设置新结果。
例如(伪代码):
def test_speed():
duration = timeit(my_function())
if duration > 60:
set_pytest_flag(it_passed_but_took_a_while)
然后稍后在
conftest.py
CUSTOM_STATUS_TIME = "_time"
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
"""Called to create a test report for each of the setup, call and teardown runtest phases of a test item."""
report = (yield).get_result()
if report.passed and call.info.it_passed_but_took_a_while:
# Error occurred in test case, which was not due to a verification
# Could be that the test case code is broken. Add custom property
# on the report to store wether the test is `time`.
setattr(report, CUSTOM_STATUS_TIME, True)
def pytest_report_teststatus(report, config):
"""Customizes the reporting of test statuses."""
if getattr(report, CUSTOM_STATUS_TIME, False):
return "time", "T", ("TIME", {"yellow": True})
这将使我的测试通过,但会向用户表明花费的时间太长。
Noe:我仅使用持续时间作为示例,我想根据我不会涉及的其他逻辑来设置我的标志。
所以问题是,我可以在测试期间设置
report
或 call
上的任何内容,以便我可以在钩子中读回它们,而不会引发异常吗?
我使用全局字典的方法作为 pytest 属性,您可以稍后在任何您想要的地方处理
# conftest.py
def pytest_configure(config):
pytest.assert_details = Dict()
在测试主体中,您可以添加任何其他信息
# add any test content you want
def test_your_details(self):
# ...
test_info = os.environ.get('PYTEST_CURRENT_TEST')
assert_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
assert_template.update({'assert_time': assert_time})
pytest.assert_details.setdefault(test_info, []).append(Dict(assert_template))
在 pytest_runtest_makereport 或 pytest_unconfigure 中修改/编辑/添加结果后,下面只是我的示例
@pytest.hookimpl(hookwrapper=True, trylast=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
for key, values in pytest.assert_details.items():
longrepr = [f"{COLOR_RESET}{'-' * 160}"]
longrepr.append(f"{key}\nFailed checks: {len(values)}\n")
for value in values:
longrepr.append(f"{COLOR_RED}{json.dumps(value, indent=4)}")
longrepr.append(f"\n{COLOR_RESET}{'-' * 160}")
report.longrepr = "\n".join(longrepr)
pytest.assert_details.clear()