前言
pytest提供的很多钩子(Hooks)方法方便我们对测试用例框架进行二次开发,可以根据自己的需求进行改造。
先学习下pytest_runtest_makereport这个钩子方法,可以更清晰的了解用例的执行过程,并获取到每个用例的执行结果。
pytest_runtest_makereport
先看下相关的源码,在 _pytest/runner.py
下,可以导入之后,点进去查看
from _pytest import runner<br><br># 对应源码<br>def pytest_runtest_makereport(item, call):<br> """ return a :py:class:_pytest.runner.TestReport
object<br> for the given :py:class:pytest.Item
and<br> :py:class:_pytest.runner.CallInfo
.<br> """
这里item是测试用例,call是测试步骤,具体执行过程如下:
- 先执行when=’setup’ 返回setup 的执行结果
- 然后执行when=’call’ 返回call 的执行结果
- 最后执行when=’teardown’返回teardown 的执行结果
运行案例
conftest.py 写 pytest_runtest_makereport 内容,打印运行过程和运行结果
conftest.py <br>import pytest<br><br>@pytest.hookimpl(hookwrapper=True, tryfirst=True)<br>def pytest_runtest_makereport(item, call):<br> print('------------------------------------')<br><br> # 获取钩子方法的调用结果<br> out = yield<br> print('用例执行结果', out)<br><br> # 3. 从钩子方法的调用结果中获取测试报告<br> report = out.get_result()<br><br> print('测试报告:%s' % report)<br> print('步骤:%s' % report.when)<br> print('nodeid:%s' % report.nodeid)<br> print('description:%s' % str(item.function.__doc__))<br> print(('运行结果: %s' % report.outcome))
test_a.py写一个简单的用例
def test_a():<br> '''用例描述:test_a'''<br> print("上海-悠悠")
运行结果如下
D:\soft\code\pytest_jenkins_demo\demo>pytest -s<br>============================= test session starts =============================<br>platform win32 -- Python 3.6.0, pytest-4.5.0, py-1.5.4, pluggy-0.13.1<br>rootdir: D:\demo<br>plugins: html-1.19.0,<br>collected 1 item<br><br>test_a.py ------------------------------------<br>用例执行结果 <br>测试报告:<br>步骤:setup<br>nodeid:test_a.py::test_a<br>description:用例描述:test_a<br>运行结果: passed<br>上海-悠悠<br>------------------------------------<br>用例执行结果 <br>测试报告:<br>步骤:call<br>nodeid:test_a.py::test_a<br>description:用例描述:test_a<br>运行结果: passed<br>.------------------------------------<br>用例执行结果 <br>测试报告:<br>步骤:teardown<br>nodeid:test_a.py::test_a<br>description:用例描述:test_a<br>运行结果: passed<br>========================== 1 passed in 0.06 seconds ===========================
从运行结果可以看出,运行用例的过程会经历三个阶段:setup-call-teardown,每个阶段都会返回的 Result 对象和 TestReport 对象,以及对象属性。
setup和teardown上面的用例默认都没有,结果都是passed。
setup和teardown
给用例写个fixture增加用例的前置和后置操作,conftest.py内容如下
import pytest<br><br>@pytest.hookimpl(hookwrapper=True, tryfirst=True)<br>def pytest_runtest_makereport(item, call):<br> print('------------------------------------')<br><br> # 获取钩子方法的调用结果<br> out = yield<br> print('用例执行结果', out)<br><br> # 3. 从钩子方法的调用结果中获取测试报告<br> report = out.get_result()<br><br> print('测试报告:%s' % report)<br> print('步骤:%s' % report.when)<br> print('nodeid:%s' % report.nodeid)<br> print('description:%s' % str(item.function.__doc__))<br> print(('运行结果: %s' % report.outcome))<br><br>@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br> print("setup 前置操作")<br> yield <br> print("teardown 后置操作")
运行结果如下
setup失败情况
当setup执行失败了,setup的执行结果的failed,后面的call用例和teardown都不会执行了
此时用例的状态是:error, 也就是用例(call)都还没开始执行,就异常了。
call失败情况
如果setup正常执行,但是测试用例call失败了
@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br> print("setup 前置操作")<br> yield<br> print("teardown 后置操作")
test_a.py用例
def test_a():<br> '''用例描述:test_a'''<br> print("上海-悠悠")<br> assert 1==0
那么此时运行的结果就是failed
teardown失败了
如果setup正常执行,测试用例call正常执行,teardown失败了,这种情况
@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br> print("setup 前置操作")<br> yield<br> print("teardown 后置操作")<br> raise Exception("teardown 失败了")
teat_a.py用例
def test_a():<br> '''用例描述:test_a'''<br> print("上海-悠悠")
最终统计的结果:1 passed, 1 error in 0.16 seconds
只获取call的结果
我们在写用例的时候,如果保证setup和teardown不报错情况,只关注测试用例本身的运行结果,前面的 pytest_runtest_makereport 钩子方法执行了三次。
可以加个判断:if report.when == “call”
import pytest<br>from _pytest import runner<br>'''<br># 对应源码<br>def pytest_runtest_makereport(item, call):<br> """ return a :py:class:_pytest.runner.TestReport
object<br> for the given :py:class:pytest.Item
and<br> :py:class:_pytest.runner.CallInfo
.<br> """<br>'''<br><br>@pytest.hookimpl(hookwrapper=True, tryfirst=True)<br>def pytest_runtest_makereport(item, call):<br> print('------------------------------------')<br><br> # 获取钩子方法的调用结果<br> out = yield<br> # print('用例执行结果', out)<br><br> # 3. 从钩子方法的调用结果中获取测试报告<br> report = out.get_result()<br> if report.when == "call":<br> print('测试报告:%s' % report)<br> print('步骤:%s' % report.when)<br> print('nodeid:%s' % report.nodeid)<br> print('description:%s' % str(item.function.__doc__))<br> print(('运行结果: %s' % report.outcome))<br><br>@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br> print("setup 前置操作")<br> yield<br> print("teardown 后置操作")
2020年第三期《python接口自动化+测试开发》课程,4月5号开学(火热报名中!)
本期上课时间:4月5号-6月27号,每周六、周日晚上20:30-22:30
联系QQ:283340479
Original: https://blog.csdn.net/weixin_29410963/article/details/113312426
Author: 李小粥
Title: pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)…
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/774497/
转载文章受原作者版权保护。转载请注明原作者出处!