当前位置: 首页 > news >正文

pytest系列——pytest_runtest_makereport钩子函数获取测试用例执行结果

前言

pytest测试框架提供的很多钩子函数方便我们对测试框架进行二次开发,可以根据自己的需求进行改造。

例如:钩子方法:pytest_runtest_makereport ,可以更清晰的了解测试用例的执行过程,并获取到每个测试用例的执行结果。

pytest_runtest_makereport方法简介

先看下相关的源码,在 _pytest/runner.py 文件下,可以导入之后查看:

image

源码:

from _pytest import runner# 对应源码def pytest_runtest_makereport(item, call):""" return a :py:class:`_pytest.runner.TestReport` objectfor the given :py:class:`pytest.Item` and:py:class:`_pytest.runner.CallInfo`."""
装饰器 pytest.hookimpl(hookwrapper=True, tryfirst=True) 解释:

@pytest.hookimpl(hookwrapper=True)装饰的钩子函数,有以下两个作用:

1、可以获取到测试用例不同执行阶段的结果(setup,call,teardown)

2、可以获取钩子方法 pytest_runtest_makereport(item, call) 的调用结果(yield返回一个测试用例执行后的result对象)和调用结果result对象中的测试报告(返回一个report对象)

pytest_runtest_makereport(item, call) 钩子函数参数解释:

1、 item 是测试用例对象;

2、 call 是测试用例的测试步骤;具体执行过程如下:

①先执行 when="setup" ,返回setup用例前置操作函数的执行结果。

②然后执行 when="call" ,返回call测试用例的执行结果。

③最后执行 when="teardown" ,返回teardown用例后置操作函数的执行结果。

第一个案例
conftest.py 文件编写 pytest_runtest_makereport 钩子方法,打印运行过程和运行结果。

# conftest.pyimport pytest@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_makereport(item, call):print('------------------------------------')# 获取钩子方法的调用结果,返回一个result对象out = yieldprint('用例执行结果', out)# 从钩子方法的调用结果中获取测试报告report = out.get_result()print('测试报告:%s' % report)print('步骤:%s' % report.when)print('nodeid:%s' % report.nodeid)print('description:%s' % str(item.function.__doc__))print(('运行结果: %s' % report.outcome))

test_a.py 写一个简单的用例:

def test_a():'''用例描述:test_a'''print("123")
运行结果:

image

image

结果分析:

从结果可以看到,测试用例的执行过程会经历3个阶段:

setup -> call -> teardown

每个阶段会返回 Result 对象和 TestReport 对象,以及对象属性。(setupteardown上面的用例默认没有,结果都是passed。)

第二个案例

给用例写个 fixture() 函数增加测试用例的前置和后置操作; conftest.py 如下:


import pytest@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_makereport(item, call):print('------------------------------------')# 获取钩子方法的调用结果out = yieldprint('用例执行结果', out)# 从钩子方法的调用结果中获取测试报告report = out.get_result()print('测试报告:%s' % report)print('步骤:%s' % report.when)print('nodeid:%s' % report.nodeid)print('description:%s' % str(item.function.__doc__))print(('运行结果: %s' % report.outcome))@pytest.fixture(scope="session", autouse=True)def fix_a():print("setup 前置操作")yieldprint("teardown 后置操作")

运行结果:

image

image

第三个案例

fixture() 函数的 setup 前置函数在执行时异常,即 setup 执行结果为 failed ,则后面的 call 测试用例与 teardown 后置操作函数都不会执行。

此时的状态是 error ,也就是代表测试用例还没开始执行就已经异常了。(在执行前置操作函数的时候就已经发生异常)


import pytest@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_makereport(item, call):print('------------------------------------')# 获取钩子方法的调用结果out = yieldprint('用例执行结果', out)# 从钩子方法的调用结果中获取测试报告report = out.get_result()print('测试报告:%s' % report)print('步骤:%s' % report.when)print('nodeid:%s' % report.nodeid)print('description:%s' % str(item.function.__doc__))print(('运行结果: %s' % report.outcome))@pytest.fixture(scope="session", autouse=True)def fix_a():print("setup 前置操作")assert 1 == 2yieldprint("teardown 后置操作")

运行结果:

image

image

第四个案例

setup 前置操作函数正常执行,测试用例 call 执行发生异常。

此时的测试用例执行结果为 failed


# conftest.pyimport pytest@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_makereport(item, call):print('------------------------------------')# 获取钩子方法的调用结果out = yieldprint('用例执行结果', out)# 3. 从钩子方法的调用结果中获取测试报告report = out.get_result()print('测试报告:%s' % report)print('步骤:%s' % report.when)print('nodeid:%s' % report.nodeid)print('description:%s' % str(item.function.__doc__))print(('运行结果: %s' % report.outcome))@pytest.fixture(scope="session", autouse=True)def fix_a():print("setup 前置操作")yieldprint("teardown 后置操作")


# test_a.pydef test_a():"""用例描述:test_a"""print("123")assert 1 == 0
运行结果:

image

image

第五个案例

setup 前置操作函数正常执行,测试用例 call 正常执行, teardown 后置操作函数执行时发生异常。

测试用例正常执行,但是测试结果中会有 error ,因为 teardown 后置操作函数在执行时发生异常


# conftest.pyimport pytest@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_makereport(item, call):print('------------------------------------')# 获取钩子方法的调用结果out = yieldprint('用例执行结果', out)# 从钩子方法的调用结果中获取测试报告report = out.get_result()print('测试报告:%s' % report)print('步骤:%s' % report.when)print('nodeid:%s' % report.nodeid)print('description:%s' % str(item.function.__doc__))print(('运行结果: %s' % report.outcome))@pytest.fixture(scope="session", autouse=True)def fix_a():print("setup 前置操作")yieldprint("teardown 后置操作")raise Exception("teardown 失败了")


# test_a.pydef test_a():'''用例描述:test_a'''print("123")
运行结果:

image

image

image

第六个案例:只获取call结果

场景:编写测试用例时,在保证 setup 前置操作函数和 teardown 后置操作函数不报错的前提下,我们一般只需要关注测试用例的执行结果,即只需要获取测试用例执行call的结果。

解决办法:因为前面的 pytest_runtest_makereport 钩子方法执行了三次。所以在打印测试报告的相关数据之气可以加个判断: if report.when == "call" 


import pytestfrom _pytest import runner'''# 对应源码def pytest_runtest_makereport(item, call):""" return a :py:class:`_pytest.runner.TestReport` objectfor the given :py:class:`pytest.Item` and:py:class:`_pytest.runner.CallInfo`."""'''@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_makereport(item, call):print('------------------------------------')# 获取钩子方法的调用结果out = yield# print('用例执行结果:', out)# 从钩子方法的调用结果中获取测试报告report = out.get_result()if report.when == "call":print('测试报告:%s' % report)print('步骤:%s' % report.when)print('nodeid:%s' % report.nodeid)print('description:%s' % str(item.function.__doc__))print(('运行结果: %s' % report.outcome))@pytest.fixture(scope="session", autouse=True)def fix_a():print("setup 前置操作")yieldprint("teardown 后置操作")

运行结果:

image

image

conftest.py 去除pytest_runtest_makereport 钩子方法,正常执行测试用例

# conftest.pyimport pytest@pytest.fixture(scope="session", autouse=True)def fix_a():print("setup 前置操作")yieldprint("teardown 后置操作")

# test_a.pydef test_a():"""用例描述:test_a"""print("123")
运行结果:

image

image

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关文章:

pytest系列——pytest_runtest_makereport钩子函数获取测试用例执行结果

前言 pytest测试框架提供的很多钩子函数方便我们对测试框架进行二次开发,可以根据自己的需求进行改造。 例如:钩子方法:pytest_runtest_makereport ,可以更清晰的了解测试用例的执行过程,并获取到每个测试用例的执行…...

Oracle数据库模式对象

文章目录 Oracle数据库模式对象 Oracle数据库模式对象 1、模式(schema)是一个数据库对象的集合。模式为一个数据库用户所有,与用户名字相同。通俗来说,模式对象就是一个用户。 2、 模式对象包括:聚簇、约束、数据库链接、触发器、维、外部过…...

各地户外分散视频监控点位,如何实现远程集中实时监看?

公司业务涉及视频监控项目承包搭建,此前某个项目需求是为某林业公司提供视频监控解决方案,需要实现各地视频摄像头的集中实时监看,以防止国家储备林的盗砍、盗伐行为。 公司原计划采用运营商专线连接各个视频监控点位,实现远程视…...

Vue笔记12-新的组件

Fragment 在Vue2中,template标签内,必须有一个div标签,作为根标签。 在Vue3中,可以没有div根标签,如果没有的话,Vue3会将多个标签包装在一个Fragment虚拟元素里。 这么做的目的:减少标签的层级…...

PySide6开发桌面程序,PySide6入门实战(下)

文章目录 系列文章索引六、样式表qss1、概述2、通用组件常用样式3、QLineEdit组件常用样式4、QpushButton常用样式5、QSlider常用样式6、QComboBox常用样式7、QProgressBar常用样式8、QMenu菜单样式9、qss选择器10、使用qss文件动态加载qss11、QDarkStyle夜间模式12、禁止子窗口…...

Java面试八股之Redis有哪些数据类型?底层实现分别是什么

Redis有哪些数据类型?底层实现分别是什么 Redis数据类型概述 Redis作为一款键值存储系统,提供了丰富多样的数据类型以满足不同场景的需求。以下是Redis支持的主要数据类型及其基本用途: String(字符串) 存储单个键…...

分布式应用系统设计:即时消息系统

即时消息(IM)系统,涉及:站内消息系统 组件如下; 客户端: WEB页面,IM桌面客户端。通过WebSocket 跟ChatService后端服务连接 Chat Service: 提供WebSocket接口,并保持跟“客户端”状态的维护。…...

【YashanDB知识库】调整NUMBER精度,再执行统计信息收集高级包偶现数据库异常退出

【问题分类】功能使用 【关键字】NUMBER类型精度修改,统计信息收集 【问题描述】存量的表将NUMBER类型的字段精度从小精度调整为大精度时,数据库收集这张业务表的统计信息时,会导致数据库异常退出。 【问题原因分析】YashanDB NUMBER字段精…...

ComfyUI+MuseV+MuseTalk图片数字人

电脑配置 GPU12G,如果自己电脑配置不够,选择云gpu,我就是用的这个,自己电脑太老配置跟不上 环境: Python 3.11.8 torch 2.2.1 cuda_12.1 资源提供: 链接:https://pan.baidu.com/s/1_idZbF…...

【Python】从基础到进阶(三):深入了解Python中的运算符与表达式

🔥 个人主页:空白诗 文章目录 一、引言二、运算符1. 算术运算符2. 比较运算符3. 逻辑运算符4. 位运算符5. 赋值运算符6. 其他运算符 三、表达式1. 表达式的定义2. 运算符的优先级3. 使用括号提升可读性4. 组合运算符与复合表达式 四、案例:计…...

C#的DllImport使用方法

1. 托管代码与非托管代码 托管代码:我们编写的C#代码(也包括.net平台上的其他语言,如VB,J#等),首先经过编译器把代码编译成中间语言(IL),当方法被调用时,公共…...

人工智能算法工程师(中级)课程11-PyTorch神经网络之循环神经网络RNN与代码详解

大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(中级)课程11-PyTorch神经网络之循环神经网络RNN与代码详解。循环神经网络(Recurrent Neural Network,RNN)是一种处理序列数据的神经网络。本文将详细介绍RNN网…...

服务端生成RSA密钥实例

RSA非对称加密算法的一种,这里分享一下服务端生成公钥和私钥的实例,并打印出来。 一:实例代码 package mainimport ("bufio""crypto/rand""crypto/rsa""crypto/x509""encoding/pem"&quo…...

Maven Nexus3 私服搭建、配置、项目发布指南

maven nexus私服搭建 访问nexus3官方镜像库,选择需要的版本下载:Docker Nexus docker pull sonatype/nexus3:3.49.0 创建数据目录并赋权 sudo mkdir /nexus-data && sudo chown -R 200 /nexus-data 运行(数据目录选择硬盘大的卷进行挂载) …...

东方博宜1627 - 暑期的旅游计划(2)

问题描述 期末考试结束了,小华语文、数学、英语三门功课分别考了 x、y、z 分,小华的家长说,如果小华三门功课中有一门考到 90 分或者 90 分以上,那么就去北京旅游,如果都没考到,那么就去南京玩。 请从键盘…...

FastAPI 学习之路(三十五)项目结构优化

之前我们创建的文件都是在一个目录中,但是在我们的实际开发中,肯定不能这样设计,那么我们去创建一个目录,叫models,大致如下。 主要目录是: __init__.py 是一个空文件,说明models是一个package…...

linux源码安装mysql8.0的小白教程

1.下载8.x版本的mysql MySQL :: Download MySQL Community Server (Archived Versions) 2.安装linux 我安装的是Rocky Linux8.6 3.设置ip地址,方便远程连接 使用nmcli或者nmtui设置或修改ip地址 4.使用远程连接工具MobaXterm操作: (1)将mysql8版本的压缩包上传到mybaxterm…...

如何评估独立站的外链质量?

要评估独立站的外链质量时,首先要看的不是别的,而是内容,跟你网站相关的文章内容才是最重要的,其他的一切其实都不重要。什么网站的DA,评级,网站的主要内容跟你的文章内容是否相关其实都不重要,…...

AI在编程领域的作用

AI(人工智能)在软件开发和许多其他领域都发挥着重要作用,但这并不意味着它在取代开发者。相反,AI更多地是在帮助开发者提高工作效率,解决复杂问题,并创造新的可能性。 探讨AI工具对开发者日常工作的影响 …...

医疗器械网络安全 | 漏洞扫描、渗透测试没有发现问题,是否说明我的设备是安全的?

尽管漏洞扫描、模糊测试和渗透测试在评估系统安全性方面是非常重要和有效的工具,但即使这些测试没有发现任何问题,也不能完全保证您的医疗器械是绝对安全的。这是因为安全性的评估是一个多维度、复杂且持续的过程,涉及多个方面和因素。以下是…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

2023赣州旅游投资集团

单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

Kafka入门-生产者

生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...

从实验室到产业:IndexTTS 在六大核心场景的落地实践

一、内容创作:重构数字内容生产范式 在短视频创作领域,IndexTTS 的语音克隆技术彻底改变了配音流程。B 站 UP 主通过 5 秒参考音频即可克隆出郭老师音色,生成的 “各位吴彦祖们大家好” 语音相似度达 97%,单条视频播放量突破百万…...