栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

pytest使用(5) - 测试报告优化

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

pytest使用(5) - 测试报告优化

1 输出原始测试报告

目前已经很过关于pytest测试报告优化的帖子,结合自己和工作经验和先知们的帖子,这里进行总结概述。原始测试用例脚本

from time import sleep
import pytest

def  test_login():
    """
    func:登录测试
    :return:
    """
    print("测试用例1")
    sleep(1)
    assert 1==1

def  test_logout():
    """
    func:登出测试
    :return:
    """
    print("测试用例2")
    assert 2==2

def  test_case03():
    """
    func:流程验证测试
    :return:
    """
    print("测试用例3")
    assert 1==3

if __name__ == '__main__':
    pytest.main(['-sv','--html=./report.html'])

输出测试报告如下:

基本能展示每个测试用例,但是实际项目中发现,一个小的版本迭代可能涉及到几百上千条测试用例,而且对于不同的测试情况下,存在基本功能一致,侧重点不同的场景,只能通过使用后缀_001,_002…来区分。比如以创建云计算-弹性伸缩中的,创建伸缩组为例,较好命名习惯是见其名知其意,比如ScalingGroup_Create_Func_001,ScalingGroup_Create_Func_002.诸如此类命名,那对于测试报告中test下展示为*_001,*_002.。不方便区分改测试用例的基本功能,因此希望将函数文档,即这里测试功能描述展示出来。那如何实现,就可以使用pytest中的钩子函数hook来实现。pytest中共有6类钩子。

参考:API Reference
Hook钩子函数完整API总结

在conftest.py脚本中使用测试函数docstring添加描述(Description)列,添加可排序时间(Time)列,并删除链接(Link)列。
既然这里是修改测试报告的相关内容,定位到使用 Reporting 报告钩子 中的函数目前共有5类,参考:pytest-html

pytest_html.hooks.pytest_html_report_title(report)

设置测试报告标题

pytest_html.hooks.pytest_html_results_summary(prefix, summary, postfix)

在Summary部分,添加自定义内容

pytest_html.hooks.pytest_html_results_table_header(cells)

定制 Result 部分,表单的头部

pytest_html.hooks.pytest_html_results_table_html(report, data)

定制Result部分,每行测试Case的内容

pytest_html.hooks.pytest_html_results_table_row(report, cells)

在完成Result渲染后,详情新增写html标记语言内容

2 pytest执行过程

pytest可以通过Hook函数(pytest_runtest_makereport)获取测试用例的执行结果。为了方便区分,新建一个文件夹为pytest_run

# code_run.py
from _pytest import runner

进入到runnner有一个 pytest_runtest_makereport 函数。

def pytest_runtest_makereport(item: Item, call: CallInfo[None]) -> TestReport:
    return TestReport.from_item_and_call(item, call)

解释一下,这里的item是测试用例,call是测试步骤。具体执行过程如下所示:

  • 先执行when=“setup”,返回setup的执行结果
  • 再执行wen=“call”,返回call的执行结果
  • 最后执行when=“teardown”,返回teardown的执行结果
# pytest_casepy
import pytest

def test_case01():
    """
    用例描述:test_Case1测试流程验证
    """
    print("用例运行时》》》》》")
    print("执行test_Case01流程验证")
    print("用例运行时》》》》》")

if __name__ == '__main__':
    pytest.main(["-s","test_case01.py"])

接着我们重写一下pytest_runtest_makereport函数,在conftest.py中

# conftest.py
import pytest

@pytest.hookimpl(hookwrapper=True,tryfirst=True)
def pytest_runtest_makereport(item,call):
    print("**************************************************************")
    # 获取常规钩子函数的调用结果,返回一个result结果
    out = yield

    print("执行结果:",out)
    # 获取调用结果的测试报告,返回一个report对象,report的对象属性包括
    # when(setup,call,teardown三个值)。nodeid(测试用例的名称),outcome(用例执行结果:passed等)
    report = out.get_result()
    print("测试步骤为: %s" % report.when)
    print("用例名称nodeid: %s" % report.nodeid)
    print("用例描述: %s" % str(item.function.__doc__))
    print("运行结果: %s" % report.outcome)
    print("测试报告: %s" % report)

执行结果如下:

这样就清晰的展示了执行过程。用例执行的过程历经:setup-call-teardown,每个阶段都会返回result对象和TestReport对象。因此通过钩子函数pytest_runtest_makereport可以捕捉到测试用例执行过程的相关数据,这些数据也就是用来对pytest-html测试报告进行优化的或者二次开发的基础。

如果只关注测试用例本身的情况,那对于上午的conftest.py可以做如下改造

# conftest.py
import pytest

@pytest.hookimpl(hookwrapper=True,tryfirst=True)
def pytest_runtest_makereport(item,call):
    print("**************************************************************")
    # 获取常规钩子函数的调用结果,返回一个result结果
    out = yield

    # print("执行结果:",out)
    # 获取调用结果的测试报告,返回一个report对象,report的对象属性包括
    # when(setup,call,teardown三个值)。nodeid(测试用例的名称),outcome(用例执行结果:passed等)
    report = out.get_result()


    if report.when == "call":
        print("测试步骤为: %s" % report.when)
        print("用例名称nodeid: %s" % report.nodeid)
        print("用例描述: %s" % str(item.function.__doc__))
        print("运行结果: %s" % report.outcome)
        print("测试报告: %s" % report)

@pytest.fixture(scope="session", autouse=True)
def fix():
    print("nsetup前置设置")
    yield
    print("nteardown后置设置")

再次执行输出结果如下:

3 测试报告新增doc

接着上面的示例,在对应的目录下新增一个conftest.py文件

from datetime import datetime
from py.xml import html
import pytest

@pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
    #  表头添加Description 和Time,同时删除表头的Link
    cells.insert(2, html.th('Description'))
    cells.insert(1, html.th('Time', class_='sortable time', col='time'))
    cells.pop()

@pytest.mark.optionalhook
def pytest_html_results_table_row(report, cells):
    # 插入对应的内容
    cells.insert(2, html.td(report.description))
    cells.insert(1, html.td(datetime.utcnow(), class_='col-time'))
    cells.pop()

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
    # description取值为用例说明'''doc'''
    outcome = yield
    report = outcome.get_result()
    report.description = str(item.function.__doc__)

再次执行输出测试报告如下所示:

既然报告中展示了summary和环境信息,这里对该部分也进行定制下。对于summary中,接上述的conftest.py中新增函数如下:

def pytest_html_results_summary(prefix):
    '''Summary部分在此设置'''
    prefix.extend([html.p("测试开发组:止语")])

新增环境信息

def pytest_configure(config):#修改Environment展示信息
    #添加项目名称
    config._metadata["项目名称"] = "弹性计算-弹性伸缩测试"
    config._metadata['测试地址'] = '192.168.50.XXX'
    # #删除Plugins
    config._metadata.pop("Plugins")
    


参考:pytest-html
pytest-html插件

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/968334.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号