Pytest学习教程_测试报告生成pytest-html(三)
前言
pytest-html 是一个用于生成漂亮的 HTML 测试报告的 pytest 插件。它可以方便地将 pytest 运行的测试结果转换为易于阅读和理解的 HTML 报告,提供了丰富的测试结果展示功能和交互性。
一、安装
# 版本查看命令
pytest版本: pytest --version
pytest-html版本: pip show pytest-html# 安装指定版本(在V3.2.0版本报告中,中文显示乱码,目前不知道什么原因)
卸载pytest-html: pip uninstall pytest-html
安装指定版本: pip install pytest-html==3.1.1# 当前演示环境版本
pytest版本:7.4.0
pytest-html版本:3.1.1
二、生成方法
1、生成默认报告
# test_run.py
import pytestdef test_A():'''执行A测试用例'''assert Truedef test_B():'''执行B测试用例'''assert Truedef test_C():'''执行C测试用例'''assert Falseif __name__ == '__main__':pytest.main(['test_run.py', '-v', '--html=./directory/report.html','--self-contained-html'])
# --html=./directory/report.html (在当前directory目录下生成普通HTML报告,CSS是独立的)
# --self-contained-html(合并CSS的HTML报告)
- 默认报告样式:

2、修改报告样式
在测试用例的同目录下新建conftest.py文件,并复制以下内容:
# conftest.py
import pytest
from py._xmlgen import html
from time import strftime# 一、修改测试报告标题
# 使用带有`optionalhook=True`的`hookimpl`装饰器
@pytest.hookimpl(optionalhook=True)
def pytest_html_report_title(report):# 设置报告标题report.title = "自动化测试报告"# 二、修改Summary部分的信息
@pytest.mark.parametrize
def pytest_html_results_summary(prefix, summary, postfix):# 添加自定义的段落信息prefix.extend([html.p("所属部门:测试组")])prefix.extend([html.p("测试人员:张三")])# 三、修改Results部分的信息
def pytest_html_results_table_header(cells):# 在索引1处插入“描述”列标题cells.insert(1, html.th('Description'))# 在索引2处插入“任务完成时间”列标题cells.insert(2, html.th('TaskCompleteTime'))# 删除最后一列“link列”cells.pop(-1)def pytest_html_results_table_row(report, cells):# 在索引1处插入报告的描述信息cells.insert(1, html.td(report.Description))# 在索引2处插入报告的任务完成时间信息cells.insert(2, html.td(report.TaskCompleteTime))# 删除最后一列“link”cells.pop(-1)@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):outcome = yieldreport = outcome.get_result()# 将报告的描述信息设置为测试项的文档字符串report.Description = str(item.function.__doc__)# 将报告的任务完成时间设置为当前时间report.TaskCompleteTime = str(strftime("%Y-%m-%d %H:%M:%S"))
- 运行test_run.py生成报告:

3、用例失败自动截图
# test_run.py
import pytest
from selenium import webdriver
from time import sleep@pytest.fixture(scope="function")
def setup_browser():"""设置和关闭浏览器的测试夹具"""driver = webdriver.Chrome()driver.maximize_window()yield driver # 返回driver对象供测试使用driver.quit() # 测试结束后关闭浏览器@pytest.fixture(params=[("https://www.baidu.com/", "百度一下,你就知道"),("https://www.csdn.net/", "CSDN - 专业开发者社区"),("https://www.youdao.com/", "网易有道失败")],ids=["百度网址验证用例", "CSDN网址验证用例", "网易网址验证用例"])
def parametrize_search_engine(request):"""参数化的搜索引擎测试夹具"""return request.paramdef test_navigation(setup_browser, parametrize_search_engine):"""测试网页是否能正常打开,并显示内容"""driver = setup_browser # 获取浏览器驱动对象keyword, engine = parametrize_search_engine# 请求网址driver.get(keyword)# 等待2秒sleep(2)assert driver.title == engine # 检查打开的页面标题是否与期望结果一致if __name__ == '__main__':pytest.main(['test_run.py', '-v', '--html=./directory/report.html','--self-contained-html'])
# conftest.py
import pytest
import pyautogui
import base64
import io@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):'''pytest_runtest_makereport是一个钩子函数,用于在每个测试用例执行完成后生成测试报告item参数表示当前正在执行的测试用例'''# 获取pytest-html插件实例,用于生成HTML格式的测试报告pytest_html = item.config.pluginmanager.getplugin('html')# yield语句暂停函数的执行,并返回给调用方一个值(被yield关键字后面的值)# 当函数恢复执行时,outcome变量将接收到yield语句后面yielded的值outcome = yield# 从outcome中获取测试用例的结果报告report = outcome.get_result()# 获取report对象的extra属性,如果不存在则返回一个空列表extra = getattr(report, 'extra', [])# 如果测试用例是在"call"或"setup"阶段执行时# 也就是在测试用例被调用执行或设置阶段出现问题时if report.when == 'call' or report.when == 'setup':# 检查报告对象中是否有wasxfail属性,表示测试用例是否被标记为预期失败(xfail)xfail = hasattr(report, 'wasxfail')# 如果测试用例被跳过且是预期失败,或者测试用例执行失败且不是预期失败if (report.skipped and xfail) or (report.failed and not xfail):# 使用pyautogui库进行屏幕截图screenshot = pyautogui.screenshot()# 创建一个BytesIO对象,用于存储屏幕截图的二进制数据screenshot_buffer = io.BytesIO()# 将屏幕截图保存到BytesIO对象中,格式为PNGscreenshot.save(screenshot_buffer, format='PNG')# 使用base64对屏幕截图的二进制数据进行编码,得到base64编码后的字符串screenshot_base64 = base64.b64encode(screenshot_buffer.getvalue()).decode('utf-8')# 构建一个HTML的div元素,其中包含一个img元素,用于显示屏幕截图# 图片源使用base64编码的字符串,点击图片时可以在新窗口打开原始截图# div元素的样式设置了图片的宽度和高度,并将其右对齐html = '<div><img src="data:image/png;base64,{}" alt="screenshot" style="width:500px;height:260px;" ' \'οnclick="window.open(this.src)" align="right"/></div>'.format(screenshot_base64)# 将构建的HTML字符串添加到extra列表中,作为测试报告的额外信息extra.append(pytest_html.extras.html(html))# 将extra列表设置为报告对象report的extra属性,更新测试报告的额外信息report.extra = extra
- 运行test_run.py生成报告:

4、完整代码
# conftest.py
import pytest
from py._xmlgen import html
from time import strftime
import pyautogui
import base64
import io# 一、修改测试报告标题
@pytest.hookimpl(optionalhook=True)
def pytest_html_report_title(report):report.title = "自动化测试报告"# 二、修改Summary部分的信息
@pytest.mark.parametrize
def pytest_html_results_summary(prefix, summary, postfix):prefix.extend([html.p("所属部门:测试组")])prefix.extend([html.p("测试人员:张三")])# 三、修改Results部分的信息,并自动截取错误截图
def pytest_html_results_table_header(cells):cells.insert(1, html.th('Description'))cells.insert(2, html.th('TaskCompleteTime'))cells.pop(-1)def pytest_html_results_table_row(report, cells):cells.insert(1, html.td(report.Description))cells.insert(2, html.td(report.TaskCompleteTime))cells.pop(-1)@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):pytest_html = item.config.pluginmanager.getplugin('html')outcome = yieldreport = outcome.get_result()report.Description = str(item.function.__doc__)report.TaskCompleteTime = str(strftime("%Y-%m-%d %H:%M:%S"))extra = getattr(report, 'extra', [])if report.when == 'call' or report.when == 'setup':xfail = hasattr(report, 'wasxfail')if (report.skipped and xfail) or (report.failed and not xfail):screenshot = pyautogui.screenshot()screenshot_buffer = io.BytesIO()screenshot.save(screenshot_buffer, format='PNG')screenshot_base64 = base64.b64encode(screenshot_buffer.getvalue()).decode('utf-8')html = '<div><img src="data:image/png;base64,{}" alt="screenshot" style="width:500px;height:260px;" ' \'οnclick="window.open(this.src)" align="right"/></div>'.format(screenshot_base64)extra.append(pytest_html.extras.html(html))report.extra = extra
相关文章:
Pytest学习教程_测试报告生成pytest-html(三)
前言 pytest-html 是一个用于生成漂亮的 HTML 测试报告的 pytest 插件。它可以方便地将 pytest 运行的测试结果转换为易于阅读和理解的 HTML 报告,提供了丰富的测试结果展示功能和交互性。 一、安装 # 版本查看命令 pytest版本: pytest --version pyte…...
模块化原理:source-map
1. webpack打包基本配置 1.安装webpack与webpack-cli npm i webpack webpack-cli 2.配置 "build":"webpack" 3. 新建webpack.config.js const path require(path); module.exports {// mode: "development",// 默认production(什么…...
【C++】开源:ncurses终端TUI文本界面库
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍ncurses终端文本界面库。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下…...
C语言的_Bool类型
C99 新增了 _Bool 类型,用于表示布尔值,即逻辑值 true 和 false。 _Bool 类型也是一种整数类型。 原则上 _Bool 类型只占用一位存储空间。 C语言将非 0 的数当为 true,0 当为 false。 代码示例: #include<stdio.h> int…...
【python爬虫】获取某一个网址下面抓取所有的a 超链接下面的内容
import requests as rq from bs4 import BeautifulSoup as bs import re# rooturl是传的是我需要查询和抓取的一个网址,可以是html js 等 def gethtml(rooturl, encoding"utf-8"):#默认解码方式utf-8response rq.get(rooturl)response.encoding encodin…...
AutoDL从0到1搭建stable-diffusion-webui
前言 AI绘画当前非常的火爆,随着Stable diffusion,Midjourney的出现将AI绘画推到顶端,各大行业均受其影响,离我们最近的AI绘画当属Stable diffusion,可本地化部署,只需电脑配备显卡即可完成AI绘画工作&…...
手动调整broker扩容后的旧topic分区
在broker扩容了两台机器之后,想让旧topic:quickstart76-events的分区也能铺满broker 1、创建一个topics-to-move.json json文件 $ vim topics-to-move.json json {"topics": [{"topic":"quickstart76-events"}],"v…...
【LeetCode-简单】剑指 Offer 25. 合并两个排序的链表(详解)
题目 入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 本题与主站 21 题相同:力扣 题目地址&#x…...
Java版工程行业管理系统源码-专业的工程管理软件-em提供一站式服务
Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目…...
【Spring】简化事件的使用,Spring提供了2种使用方式
Spring中事件可以配置顺序,利用线程池还可以做异步线程通知。怎么样使用事件?Spring简化事件的使用,Spring提供了2种使用方式:面向接口和面向EventListener注解。 1,面相接口的方式 案例 发布事件 需要先继承ApplicationEventP…...
探究Spring事务:了解失效场景及应对策略
在现代软件开发中,数据的一致性和完整性是至关重要的。为了保证这些特性,Spring框架提供了强大的事务管理机制,让开发者能够更加自信地处理数据库操作。然而,事务并非银弹,存在一些失效的情景,本文将带您深…...
Maven Manifold 条件编译
Maven 配置 通过 Maven 的不同 profile 实现不同环境传递不同符号。另外 lombok 可以 manifold 一同使用,见下方配置。 <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.targ…...
4.数组与基本数学函数
一、数组 1.概念 数组是存放相同类型对象的容器,数组中存放的对象没有名字,而是要通过其所在的位置访问。数组中的每一个元素都相当于一个普通的变量,可以和普通变量一样进行赋值操作。 数组可以帮助我们批量地处理相同数据类型的相关数据…...
python与深度学习(十六):CNN和宝可梦模型二
目录 1. 说明2. 宝可梦模型的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 数据处理和归一化2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章宝可梦模型训练的模型…...
PTA 1030 Travel Plan
个人学习记录,代码难免不尽人意。 A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/h…...
MFC、Qt、WPF?该用哪个?
MFC、Qt和WPF都是流行的框架和工具,用于开发图形用户界面(GUI)应用程序。选择哪个框架取决于你的具体需求和偏好。MFC(Microsoft Foundation Class)是微软提供的框架,使用C编写,主要用于Windows…...
使用logback记录日志
1. Pom引用依赖 <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> </dependency> 2. logback.xml <?xml version"1.0" encoding"U…...
企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理) em
工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…...
【安装】XMind2022XMind2020安装教程(资源)
Xmind是一个制作思维导图很便利的软件。 1.资源链接 Xmind2022: 链接:https://pan.baidu.com/s/1j4DFedxxX2YJ3HBy1-MpHw?pwdxmin 提取码:xmin Xmind2020: 链接:https://pan.baidu.com/s/1wNqMApuy0yoBF2CvpBDpDA?pwdxmin 提取码&#x…...
Windows下QT Creator安装MinGW 32bit编译器
前言 注:本作者是基于FFmpeg开发需要,故在Windows下QT Creator中安装MinGW 32bit编译器!其它型号编译器参照此文章基本可以实现! 一、下载需要的编译器 1、下载链接 链接: 链接:https://pan.baidu.com/…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
