240
生活,简单就好!

Pytest学习-通过hooks函数(pytest_runtest_makereport)获取用例结果

Pytest中提供了很多钩子函数,可以方便我们基于此进行二次开发,另外通过对Pytest钩子函数的学习,我们也能够更好的理解到其在用例执行的各阶段到底做了哪些工作。

今天我们将学习Pytest中的钩子函数:pytest_runtest_makereport,它可以让我们获取到用例执行结果。

钩子函数的使用

我们可以在Pytest源码中的 runner.py 文件下找到 pytest_runtest_makereport() 钩子函数,大致如下:

def pytest_runtest_makereport(item, call):
    return TestReport.from_item_and_call(item, call)

该函数操作时传入 测试用例 item 和 测试步骤 call,返回的数据是测试用例的执行结果。下面是简单的示例:

# test_01.py
import pytest


def test_01():
    """用例描述:XXXXXX"""
    print("测试一下")
    assert 1
# conftest.py
import pytest


@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    print("------------------------Start---------------------------")
    out = yield
    res = out.get_result()
    print("执行结果:{}".format(res))
    print("测试用例:{}".format(item))
    print("测试步骤:{}".format(call))
    print("------------------------End---------------------------")

把上面的用例执行后,得到如下结果:

用例执行结果

从上方输出的信息可以知道,我们在 Pytest 中执行一条用例的时候,需要经过以下3个阶段:

  • 最先执行 when='setup' 的前置操作
  • 接着执行 when='call' 的用例部分
  • 最后执行 when='teardown' 的后置操作

上面的每一个阶段,都会返回相应的执行结果,如果用例中不存在前置/后置操作,那么该阶段默认 outcome='passed'

当然对于这3个阶段,也都可能会出现失败的情况。为了更方便模拟操作失败的情况,我们在 conftest.py 中使用 fixture 增加一个函数,然后设置为自动调用。

@pytest.fixture(scope="function", autouse=True)
def setup_teardown():
    print("------------------------这是setup前置操作---------------------------")
    yield
    print("------------------------这是teardown后置操作---------------------------")

setup前置操作失败

为了让用例在前置操作中出现失败,我们可以简单修改下 conftest.py 代码:

@pytest.fixture(scope="function", autouse=True)
def setup_teardown():
    assert 0
    print("------------------------这是setup前置操作---------------------------")
    yield
    print("------------------------这是teardown后置操作---------------------------")

然后重新运行用例,得到结果如下:

setup前置操作失败

从用例结果中可以看到,我们在 Pytest 中执行用例时,如果在setup前置操作中就出现失败,那么其不会再调用测试用例和执行后置操作(上面 teardown 的信息也没有打印出来),而用例的执行结果为:error

call测试用例失败

为了让用例在 call 调用中出现失败,我们可以简单修改下 test_01.py 代码:

import pytest


def test_01():
    """用例描述:XXXXXX"""
    print("断言失败")
    assert 0

重新运行用例,得到结果如下:

call测试用例失败

从用例结果中可以看到,我们在 Pytest 中执行用例时,setup前置操作成功,但在call测试用例中出现失败,那么其会继续执行后置操作,最后用例的执行结果为:failed

teardown后置操作失败

为了让用例在前置操作中出现失败,我们可以简单修改下 conftest.py 代码:

@pytest.fixture(scope="function", autouse=True)
def setup_teardown():
    print("------------------------这是setup前置操作---------------------------")
    yield
    print("------------------------这是teardown前置操作---------------------------")
    assert 0

重新运行用例,得到结果如下:

teardown后置操作失败

从用例结果中可以看到,我们在 Pytest 中执行用例时,teardown后置操作失败,那么最后用例的结果为:1 passed, 1 error

用例执行结果

获取用例执行时的信息

有时候,我们想要获取测试用例执行的详细信息,比如打印用例描述,或在用例执行失败后打印日志等信息,那么我们可以优化下代码:

@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    print("------------------------Start---------------------------")
    out = yield  # 钩子函数的调用结果
    res = out.get_result()  # 获取用例执行结果
    print("执行结果:{}".format(res))
    if res.when == "call" and res.outcome == "failed":  # 只获取call用例失败时的信息
        print("测试用例:{}".format(item))
        print("用例描述:{}".format(item.function.__doc__))
        print("测试步骤:{}".format(call))
        print("用例失败异常信息:{}".format(call.excinfo))
        print("用例失败时的详细日志:{}".format(res.longrepr))
    print("------------------------End---------------------------")

重新运行用例,得到结果如下:

获取用例执行时的信息g

posted @ 2021-06-12 21:24  wintest  阅读(1252)  评论(0编辑  收藏  举报