当前位置: 首页 > 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…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...