使用pytest_runtest_makereport进行失败截图
在执行UI自动化的时候,遇到错误没有截图的话,比较难以定位
所以使用pytest
的钩子函数来进行失败后的操作
https://docs.pytest.org/en/7.0.x/reference/reference.html?highlight=pytest_runtest_makereport#std-hook-pytest_runtest_makereport
pytest_runtest_makereport
(item, call)
Called to create a TestReport
for each of the setup, call and teardown runtest phases of a test item.
See pytest_runtest_protocol
for a description of the runtest protocol.
Parameters:
call (CallInfo[None]) – The `CallInfo` for the phase.
item (Item) –
Return type:Optional[TestReport]
Stops at first non-None result, see firstresult: stop at first non-None result.
For deeper understanding you may look at the default implementation of these hooks in
_pytest.runner
and maybe also in_pytest.pdb
which interacts with_pytest.capture
and its input/output capturing in order to immediately drop into interactive debugging when a test failure occurs.
先使用out = yield
来暂停用例执行完的时候,然后判断一下当前用例执行的结果
如果结果是failed
或者是error
,说明用例出错了,这时候就需要进行截图了
因为是UI自动化测试,所以我们传入头部中肯定有个对象包含了driver
对象,拿到了它,我们就可以进行截图了
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
"""
pytest 失败后执行
:param item: 测试用例
:param call: 测试步骤
:return:
"""
out = yield
result = out.get_result()
logger.info(f"测试报告:{result}")
logger.info(f"执行耗时:{call.duration}")
if result.outcome in ['failed', 'error']:
for k, v in item.funcargs.items():
if hasattr(v, 'driver'):
attach_png(f'{TEST_PIC}/{int(time.time())}.png', "失败截图", v)
break
使用pytest_assume_fail进行失败截图
pytest有个比较好用的插件:pytest.assume
,可以很方便的进行多个错误的断言,不会像使用assert
一样,直接终止用例执行。
在site-packages/pytest_assume/hooks.py
文件中很容易就可以找到这个插件的钩子函数
def pytest_assume_fail(lineno, entry):
"""
Hook to manipulate user-defined data in-case of assumption failure.
lineno: Line in the code from where asumption failed.
entry: The assumption failure message generated from assume() call
"""
pass
每次触发pytest.assume(False)
的时候就会调用一次这个钩子函数
我们重新下这个钩子函数就可以实现,每次失败都自动截图了
具体见:看钩!assert/pytest-assume失败后截图
import inspect
def pytest_assume_fail(lineno, entry):
"""
assume 断言报错截图
"""
print(entry)
for i in inspect.stack():
if os.path.split(i.filename)[1].startswith('test_'):
try:
for k, v in i.frame.f_locals.items():
if hasattr(v, 'driver'):
attach_png(f'{TEST_PIC}/{int(time.time())}.png', f"失败截图_{int(time.time())}", v)
break
except Exception:
pass