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

使用Pytest生成HTML测试报告

背景

最近开发有关业务场景的功能时,涉及的API接口比较多,需要自己模拟多个业务场景的自动化测试(暂时不涉及性能测试),并且在每次测试完后能够生成一份测试报告。

考虑到日常使用Python自带的UnitTest,所以先从官方文档下手,了解到有相关的TestTextRunner:https://docs.python.org/zh-cn/3/library/unittest.html?highlight=unittest#unittest.TextTestRunner。

自带的TextTestRunner每次能把测试结果输出到流中的测试运行器,可以简单根据verbosity调整每次测试结果输出的信息,但是都太基础了,如果我想在测试过程中打印一些请求参数或者docstring,看了一下UnitTest内置的方法,实现过程可能会比较繁琐。

然后在网上找了一下轮子工具、html-testrunner、beautifulreport,这些工具生成的网页css、js都是使用公网的CDN,由于内网环境,不适合。

后面看了一些技术文章很多都是使用Pytest,之前有相关Pytest的基础使用经验,大概了解一下,决定根据Pytest+pytest-html满足当前测试场景。

模块安装

pip install pytest
pip install pytest-html

方案设计

pytest.ini

首先定义pytest.ini(pytest的基础配置文件,和测试文件在同一目录,使用pytest命令时会先读取该文件):

[pytest]
log_cli = True
log_cli_level = INFO

备注:开启日志消息打印,设置日志记录捕获的最低消息级别为INFO。

conftest.py

设置conftest.py(没有自己创建,同样是和测试文件同个目录下,用于pytest-html生成测试报告的配置文件):


# --*-- coding: utf-8 --*--
from datetime import datetime
from py.xml import html
import pytestdef pytest_html_report_title(report):report.title = "测试报告"def pytest_html_results_table_header(cells):cells.insert(2, html.th("Description"))cells.insert(1, html.th("Time", class_="sortable time", col="time"))cells.pop()def pytest_html_results_table_row(report, cells):cells.insert(2, html.td(report.description))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.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):outcome = yieldreport = outcome.get_result()report.description = str(item.function.__doc__)

通过设置钩子函数分别修改测试报告的列,添加描述列、测试用例耗时时间列、删除链接列,我这里是直接参考官方文档中给出的示例:https://pytest-html.readthedocs.io/en/latest/user_guide.html#creating-a-self-contained-report,有兴趣的可以研究一下。

测试用例

根据Pytest的官方文档,Pytest同样是支持UnitTest的功能,所以可以在原有的基础上直接运行Pytest:


# -*- coding: utf-8 -*-
# @Author: linshukai
# @Desc: pytestc测试用例
# @Date: 20220827import unittest
import pytest
import loggingimport requestsclass TestString(unittest.TestCase):def test_upper_method(self):"""测试字符串大写"""self.assertEqual("linshukai".upper(), "LINSHUKAI")logging.info("测试linshukai")def test_lower_method(self):"""测试字符串小写"""self.assertEqual( "ZhangSan".lower(), "zhangsan")logging.info("测试ZhangSan")def test_count_method(self):"""测试字符串长度统计"""self.assertEqual( len("zhangsan"), 8)logging.info("测试Zhangsan")class TestString2(unittest.TestCase):def test_get_html(self):"""测试请求网页状态码是否正常"""response = requests.get("http://www.baidu.com")self.assertEqual(response.status_code, 500)if __name__ == "__main__":pytest.main(["pytest_example.py", "--html=report.html", "--self

备注:简单写了几个测试用例,需要特别说明的是可以通过pytest.main()方法,直接在Python代码中调用Pytest,所以我每次只需要执行这个脚本就行,当然也可以选择在命令行界面通过Pytest命令调用指定测试文件执行指定测试用例。

另外一个地方需要注意的是–self-contained-html这个参数主要是针对pytest-html模块,由于默认pytest-html中生成测试报告的网页和CSS文件都是分开来存储的,如果想直接将css文件合并到html中,这样分享测试报告的时候也更加方便,所以只需要加入这个参数即可–self-contained-html。

预期效果
在这里插入图片描述

 预期会出现的问题

Pytest中使用requests,抛出错误,但不影响测试结果,抛出的异常:

Windows fatal exception: code 1073807366

解决方式,降低Pytest为4.6.11版本后,异常就不会抛出,但是pytest-html需要6.0版本上的Pytest,由于不影响测试结果,更加完善的解决方法后续再研究。


          【下面是我整理的2023年最全的软件测试工程师学习知识架构体系图】


一、Python编程入门到精通


二、接口自动化项目实战  

三、Web自动化项目实战


四、App自动化项目实战 

五、一线大厂简历


六、测试开发DevOps体系 

七、常用自动化测试工具


八、JMeter性能测试 

九、总结(尾部小惊喜)

生命不息,奋斗不止。每一份努力都不会被辜负,只要坚持不懈,终究会有回报。珍惜时间,追求梦想。不忘初心,砥砺前行。你的未来,由你掌握!

生命短暂,时间宝贵,我们无法预知未来会发生什么,但我们可以掌握当下。珍惜每一天,努力奋斗,让自己变得更加强大和优秀。坚定信念,执着追求,成功终将属于你!

只有不断地挑战自己,才能不断地超越自己。坚持追求梦想,勇敢前行,你就会发现奋斗的过程是如此美好而值得。相信自己,你一定可以做到!

相关文章:

使用Pytest生成HTML测试报告

背景 最近开发有关业务场景的功能时,涉及的API接口比较多,需要自己模拟多个业务场景的自动化测试(暂时不涉及性能测试),并且在每次测试完后能够生成一份测试报告。 考虑到日常使用Python自带的UnitTest,所…...

DSA之图(4):图的应用

文章目录 0 图的应用1 生成树1.1 无向图的生成树1.2 最小生成树1.2.1 构造最小生成树1.2.2 Prim算法构造最小生成树1.2.3 Kruskal算法构造最小生成树1.2.4 两种算法的比较 1.3 最短路径1.3.1 两点间最短路径1.3.2 某源点到其他各点最短路径1.3.3 Dijkstra1.3.4 Floyd 1.4 拓扑排…...

[SQL挖掘机] - 窗口函数 - row_number

介绍: row_number() 是一种常用的窗口函数,它为结果集中的每一行分配一个唯一的数字。这个数字的分配基于指定的排序顺序,并且不会跳过相同的排名。 用法: row_number() 函数的语法如下: row_number() over ([partition by 列名1, 列名2,…...

【论文阅读】通过解缠绕表示学习提升领域泛化能力用于主题感知的作文评分

摘要 本文工作聚焦于从领域泛化的视角提升AES模型的泛化能力,在该情况下,目标主题的数据在训练时不能被获得。本文提出了一个主题感知的神经AES模型(PANN)来抽取用于作文评分的综合的表示,包括主题无关(pr…...

二分查找P1873 [COCI2011-2012#5] EKO / 砍树

P1873 [COCI2011-2012#5] EKO / 砍树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这个题就是给新手练手的&#xff0c;在那个位置上在进行&#xff0c;寻找合适的砍树高度&#xff0c;下面在介绍一个二分查找的模板 int binarySearch(vector<int>& nums, int t…...

【BOOST程序库】正则表达式相关操作

基本概念这里不解释了&#xff0c;代码中详细解释了BOOST程序库中对于正则表达式常用方法的详细用法。 #include <iostream> #include <string>//正则表达式头文件 #include <boost/xpressive/xpressive.hpp>int main() {//声明正则&#xff1a;boost::pres…...

阿里云国际版在使用过程中应该注意什么呢?

为确保系统稳定性&#xff0c;用户不得进行以下操作。否则&#xff0c;阿里云可能无法解决由以下违规操作引起的问题&#xff1a; 1) Windows系统中的PV Drivers 程序不可删除 PV Drivers程序为服务器虚拟化驱动程序&#xff0c;请不要针对该程序进行任何操作&#xff0c;如果删…...

Flutter Provider 共享状态管理

在使用Provider的时候&#xff0c;我们主要关心三个概念&#xff1a; ChangeNotifier&#xff1a;真正数据&#xff08;状态&#xff09;存放的地方ChangeNotifierProvider&#xff1a;Widget树中提供数据&#xff08;状态&#xff09;的地方&#xff0c;会在其中创建对应的Ch…...

std vector 用法

使用vector&#xff0c;需添加头文件#include&#xff0c;要使用sort或find&#xff0c;则需要添加头文件#include。函数封装在命名空间std中&#xff0c;使用&#xff1a;using namespace std; 1、vector的初始化 std::vector<int> nVec;    // 空对象 std::vecto…...

vue vite ts electron ipc addon-napi c arm64

初始化 因网络问题建议使用 cnpm 代替 npm npm init vue # 全选 yes npm i # 进入项目目录后使用 npm i electron electron-builder -D npm i commander -D # 额外组件electron 新建 plugins、src/electron 文件夹 添加 src/electron/background.ts 属于主进程 ipcMain.o…...

机器人科普--AGILOX 叉车

机器人科普--AGILOX 叉车 1 概述2 导航3 驱动轮组4 叉举参考 1 概述 AGILOX 叉车&#xff0c;不需要画地图路径&#xff0c;很厉害。 2 导航 中间路径自由导航&#xff0c;末端规划出轨迹路线&#xff0c;并使用优良的控制器做轨迹追踪。 AGILOX &#xff5c; 10 Min setu…...

Django的生命周期流程图(补充)、路由层urls.py文件、无名分组和有名分组、反向解析(无名反向解析、有名反向解析)、路由分发、伪静态

一、orm的增删改查方法&#xff08;补充&#xff09; 1. 查询resmodels.表名(类名).objects.all()[0]resmodels.表名(类名).objects.filter(usernameusername, passwordpassword).all()res models.表名(类名).objects.first() # 判断&#xff0c;判断数据是否有# res如果查询…...

selenium交互代码

一&#xff1a;selenium交互 用selenium打开网页后&#xff0c;也可以做一系列真人的操作&#xff0c;也就是利用selenium和浏览器进行交互&#xff0c;可利用以下几个函数进行操作&#xff1a; input.send_keys() 传递输入内容给某输入框button.click() 点击某按钮browser.e…...

下载远程服务器文件

业务需求:下载某云盘的视频文件存储到本地 测试代码 RequestMapping("testVideo")public String test() {try {SimpleDateFormat DATE_FORMAT new SimpleDateFormat("yyyy/MM/dd/");//组装本地保存地址StringBuilder filePath new StringBuilder(StoreP…...

[SQL挖掘机] - 索引

介绍: 当你在数据库中进行查询时&#xff0c;索引是一种用于提高查询性能的重要工具。索引是对表中的一列或多列进行排序的数据结构&#xff0c;它可以快速定位到满足特定条件的记录&#xff0c;从而减少了查询所需的时间和资源。 在数据库中使用索引的主要好处包括&#xff…...

C++STL库中的list

文章目录 list的介绍及使用 list的常用接口 list的模拟实现 list与vector的对比 一、list的介绍及使用 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list的底层是双向带头循环链表结构&#xff0c;双向带头循…...

【LeetCode 75】第十七题(1493)删掉一个元素以后全为1的最长子数组

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给一个数组&#xff0c;求删除一个元素以后能得到的连续的最长的全是1的子数组。 我们可以先单独统计出连续为1的子数组分别长度…...

配置IPv6 over IPv4 GRE隧道示例

组网需求 如图1&#xff0c;两个IPv6网络分别通过SwitchA和SwitchC与IPv4公网中的SwitchB连接&#xff0c;客户希望两个IPv6网络中的PC1和PC2实现互通。 其中PC1和PC2上分别指定SwitchA和SwitchC为自己的缺省网关。 图1 配置IPv6 over IPv4 GRE隧道组网图 配置思路 要实现I…...

Google Earth Engine谷歌地球引擎提取多波段长期反射率数据后绘制折线图并导出为Excel

本文介绍在谷歌地球引擎GEE中&#xff0c;提取多年遥感影像多个不同波段的反射率数据&#xff0c;在GEE内绘制各波段的长时间序列走势曲线图&#xff0c;并将各波段的反射率数据与其对应的成像日期一起导出为.csv文件的方法。 本文是谷歌地球引擎&#xff08;Google Earth Engi…...

第三大的数

414、第三大的数 class Solution {public int thirdMax(int[] nums) {Arrays.sort(nums);int tempnums[0];int ansnums[0];int count 0;// if(nums.length<3){// return nums[nums.length-1];// }// else {for(int inums.length-1;i>0;i--){if (nums[i]>nums[i…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...