pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)…

前言

pytest提供的很多钩子(Hooks)方法方便我们对测试用例框架进行二次开发,可以根据自己的需求进行改造。
先学习下pytest_runtest_makereport这个钩子方法,可以更清晰的了解用例的执行过程,并获取到每个用例的执行结果。

pytest_runtest_makereport

先看下相关的源码,在 _pytest/runner.py下,可以导入之后,点进去查看

from _pytest import runner<br><br># &#x5BF9;&#x5E94;&#x6E90;&#x7801;<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>    # &#x83B7;&#x53D6;&#x94A9;&#x5B50;&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x7ED3;&#x679C;<br>    out = yield<br>    print('&#x7528;&#x4F8B;&#x6267;&#x884C;&#x7ED3;&#x679C;', out)<br><br>    # 3. &#x4ECE;&#x94A9;&#x5B50;&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x7ED3;&#x679C;&#x4E2D;&#x83B7;&#x53D6;&#x6D4B;&#x8BD5;&#x62A5;&#x544A;<br>    report = out.get_result()<br><br>    print('&#x6D4B;&#x8BD5;&#x62A5;&#x544A;&#xFF1A;%s' % report)<br>    print('&#x6B65;&#x9AA4;&#xFF1A;%s' % report.when)<br>    print('nodeid&#xFF1A;%s' % report.nodeid)<br>    print('description:%s' % str(item.function.__doc__))<br>    print(('&#x8FD0;&#x884C;&#x7ED3;&#x679C;: %s' % report.outcome))

test_a.py写一个简单的用例

def test_a():<br>    '''&#x7528;&#x4F8B;&#x63CF;&#x8FF0;:test_a'''<br>    print("&#x4E0A;&#x6D77;-&#x60A0;&#x60A0;")

运行结果如下

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>&#x7528;&#x4F8B;&#x6267;&#x884C;&#x7ED3;&#x679C; <br>&#x6D4B;&#x8BD5;&#x62A5;&#x544A;&#xFF1A;<br>&#x6B65;&#x9AA4;&#xFF1A;setup<br>nodeid&#xFF1A;test_a.py::test_a<br>description:&#x7528;&#x4F8B;&#x63CF;&#x8FF0;:test_a<br>&#x8FD0;&#x884C;&#x7ED3;&#x679C;: passed<br>&#x4E0A;&#x6D77;-&#x60A0;&#x60A0;<br>------------------------------------<br>&#x7528;&#x4F8B;&#x6267;&#x884C;&#x7ED3;&#x679C; <br>&#x6D4B;&#x8BD5;&#x62A5;&#x544A;&#xFF1A;<br>&#x6B65;&#x9AA4;&#xFF1A;call<br>nodeid&#xFF1A;test_a.py::test_a<br>description:&#x7528;&#x4F8B;&#x63CF;&#x8FF0;:test_a<br>&#x8FD0;&#x884C;&#x7ED3;&#x679C;: passed<br>.------------------------------------<br>&#x7528;&#x4F8B;&#x6267;&#x884C;&#x7ED3;&#x679C; <br>&#x6D4B;&#x8BD5;&#x62A5;&#x544A;&#xFF1A;<br>&#x6B65;&#x9AA4;&#xFF1A;teardown<br>nodeid&#xFF1A;test_a.py::test_a<br>description:&#x7528;&#x4F8B;&#x63CF;&#x8FF0;:test_a<br>&#x8FD0;&#x884C;&#x7ED3;&#x679C;: 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>    # &#x83B7;&#x53D6;&#x94A9;&#x5B50;&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x7ED3;&#x679C;<br>    out = yield<br>    print('&#x7528;&#x4F8B;&#x6267;&#x884C;&#x7ED3;&#x679C;', out)<br><br>    # 3. &#x4ECE;&#x94A9;&#x5B50;&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x7ED3;&#x679C;&#x4E2D;&#x83B7;&#x53D6;&#x6D4B;&#x8BD5;&#x62A5;&#x544A;<br>    report = out.get_result()<br><br>    print('&#x6D4B;&#x8BD5;&#x62A5;&#x544A;&#xFF1A;%s' % report)<br>    print('&#x6B65;&#x9AA4;&#xFF1A;%s' % report.when)<br>    print('nodeid&#xFF1A;%s' % report.nodeid)<br>    print('description:%s' % str(item.function.__doc__))<br>    print(('&#x8FD0;&#x884C;&#x7ED3;&#x679C;: %s' % report.outcome))<br><br>@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br>    print("setup &#x524D;&#x7F6E;&#x64CD;&#x4F5C;")<br>    yield <br>    print("teardown &#x540E;&#x7F6E;&#x64CD;&#x4F5C;")

运行结果如下

pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)...

setup失败情况

当setup执行失败了,setup的执行结果的failed,后面的call用例和teardown都不会执行了

pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)...

此时用例的状态是:error, 也就是用例(call)都还没开始执行,就异常了。

call失败情况

如果setup正常执行,但是测试用例call失败了

@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br>    print("setup &#x524D;&#x7F6E;&#x64CD;&#x4F5C;")<br>    yield<br>    print("teardown &#x540E;&#x7F6E;&#x64CD;&#x4F5C;")

test_a.py用例

def test_a():<br>    '''&#x7528;&#x4F8B;&#x63CF;&#x8FF0;:test_a'''<br>    print("&#x4E0A;&#x6D77;-&#x60A0;&#x60A0;")<br>    assert 1==0

pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)...

那么此时运行的结果就是failed

teardown失败了

如果setup正常执行,测试用例call正常执行,teardown失败了,这种情况

@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br>    print("setup &#x524D;&#x7F6E;&#x64CD;&#x4F5C;")<br>    yield<br>    print("teardown &#x540E;&#x7F6E;&#x64CD;&#x4F5C;")<br>    raise Exception("teardown &#x5931;&#x8D25;&#x4E86;")

teat_a.py用例

def test_a():<br>    '''&#x7528;&#x4F8B;&#x63CF;&#x8FF0;:test_a'''<br>    print("&#x4E0A;&#x6D77;-&#x60A0;&#x60A0;")

pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)...

最终统计的结果:1 passed, 1 error in 0.16 seconds

pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)...

只获取call的结果

我们在写用例的时候,如果保证setup和teardown不报错情况,只关注测试用例本身的运行结果,前面的 pytest_runtest_makereport 钩子方法执行了三次。
可以加个判断:if report.when == “call”

import pytest<br>from _pytest import runner<br>'''<br># &#x5BF9;&#x5E94;&#x6E90;&#x7801;<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>    # &#x83B7;&#x53D6;&#x94A9;&#x5B50;&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x7ED3;&#x679C;<br>    out = yield<br>    # print('&#x7528;&#x4F8B;&#x6267;&#x884C;&#x7ED3;&#x679C;', out)<br><br>    # 3. &#x4ECE;&#x94A9;&#x5B50;&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x7ED3;&#x679C;&#x4E2D;&#x83B7;&#x53D6;&#x6D4B;&#x8BD5;&#x62A5;&#x544A;<br>    report = out.get_result()<br>    if report.when == "call":<br>        print('&#x6D4B;&#x8BD5;&#x62A5;&#x544A;&#xFF1A;%s' % report)<br>        print('&#x6B65;&#x9AA4;&#xFF1A;%s' % report.when)<br>        print('nodeid&#xFF1A;%s' % report.nodeid)<br>        print('description:%s' % str(item.function.__doc__))<br>        print(('&#x8FD0;&#x884C;&#x7ED3;&#x679C;: %s' % report.outcome))<br><br>@pytest.fixture(scope="session", autouse=True)<br>def fix_a():<br>    print("setup &#x524D;&#x7F6E;&#x64CD;&#x4F5C;")<br>    yield<br>    print("teardown &#x540E;&#x7F6E;&#x64CD;&#x4F5C;")

pytest 不执行teardown_pytest文档33Hooks函数获取用例执行结果(pytest_runtest_makereport)...

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/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球