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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/18109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VGN N75pro说明书

VGN N75pro说明书 1、封面和最后一页 2、第01、02、03 3、第04 4、第05

面试总结-Redis篇章(十)——Redis哨兵模式、集群脑裂

Redis哨兵模式、集群脑裂 哨兵模式哨兵的作用服务状态监控 Redis集群&#xff08;哨兵模式&#xff09;脑裂解决办法 哨兵模式 为了保证Redis的高可用&#xff0c;Redis提供了哨兵模式 哨兵的作用 服务状态监控 Redis集群&#xff08;哨兵模式&#xff09;脑裂 假设由于网络原…

344.翻转字符串+387.字符串中的第一个唯一字符

目录 一、翻转字符串 二、字符串中的第一个唯一字符 一、翻转字符串 344. 反转字符串 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:void reverseString(vector<char>& s) {int start0;int end s.size()-1;while(start < end){swap(s[sta…

3ds MAX 绘制喷泉

首先绘制一个小圆柱体当做喷头&#xff1a; 在粒子系统内选择【超级喷射】&#xff0c;并设置对应的参数&#xff1a; 轴和平面的扩散代表了我们看到的水柱能占据多大的面积 另外比较重要的参数是粒子运动和粒子计时 前者是粒子移动的时间也就是喷射的速度 后者代表了喷射出的…

构建语言模型:BERT 分步实施指南

学习目标 了解 BERT 的架构和组件。了解 BERT 输入所需的预处理步骤以及如何处理不同的输入序列长度。获得使用 TensorFlow 或 PyTorch 等流行机器学习框架实施 BERT 的实践知识。了解如何针对特定下游任务(例如文本分类或命名实体识别)微调 BERT。为什么我们需要 BERT? 正…

【VTK】基于读取出来的 STL 模型,当用户点击鼠标左键时,程序将获取点击位置的点,显示其坐标,并设置它为模型的旋转原点

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 class PointPickedSignal : public QObjectclass MouseInteractorCommand : public vtkCommandvoid A::on_pushButtonSelected_clicked()void A::on…

vue3搭建(vite+create-vue)

目录 前提条件 输入命令 对于Add an End-to-End Testing Solution nightwatch和Cypress 和 Playwright 运行 前提条件 熟悉命令行已安装 16.0 或更高版本的 Node.js &#xff08;node -v查看版本&#xff09; 输入命令 npm init vuelatest 这一指令将会安装并执行 create-…

Meta AI研究团队新AI模型: Llama 2 大语言模型

Llama是Facebook Research团队开发的基础语言模型集&#xff0c;旨在提供广泛的语言理解能力。它基于转换器架构&#xff0c;参数范围从7B到65B。通过使用Llama模型&#xff0c;研究人员和开发人员可以构建更先进的自然语言处理系统。您可以在GitHub上找到相关的代码和资源&…

kotlin 编写一个简单的天气预报app(四)增加界面显示

编写界面来显示返回的数据 用户友好性&#xff1a;通过界面设计和用户体验优化&#xff0c;可以使天气信息更易读、易理解和易操作。有效的界面设计可以提高用户满意度并提供更好的交互体验。 增加城市名字的TextView <TextViewandroid:id"id/textViewCityName"…

CentOS 7虚拟机 虚拟机安装安装增强VBox_GAs_6.1.22失败:modprobe vboxguest failed

我安装的CentOS 在安装增强工具的时候报错: 查阅资料后 &#xff0c;解决方法&#xff1a; 1、更新kernel内核版本&#xff1a; yum update kernel -y //安装kernel-devel和gcc编译工具链yum install -y kernel-devel gcc//更新kernel和kernel-devel到最新版本yum -y upgrade …

就业并想要长期发展选数字后端还是ic验证?

“就业并想要长期发展选数字后端还是ic验证&#xff1f;” 这是知乎上的一个热点问题&#xff0c;浏览量达到了13,183。看来有不少同学对这个问题感到疑惑。之前更新了数字后端&数字验证的诸多文章&#xff0c;从学习到职业发展&#xff0c;都写过&#xff0c;唯一没有做过…

windows编译ncnn

官方代码https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-windows-x64-using-visual-studio-community-2017 编译工具 visual studio 2017 一、编译protobuf 1、下载protobuf protobuf-3.11.2&#xff1a;https://github.com/google/protobuf/archive/v3.11…

指针初阶(超详解)

指针初阶 1.指针是什么2.指针和指针类型2.1 指针-整数2.2 指针的解引用 3.野指针3.1 野指针成因3.2如何避免野指针 4.指针运算4.1 指针-整数4.2 指针-指针4.3 指针的关系运算 5.指针和数组6.二级指针7.指针数组 1.指针是什么 指针是什么&#xff1f; 指针理解的2个要点&#xf…

maven下载按照及初次使用相关配置

maven下载按照及初次使用相关配置 一、下载 与安装 依赖Java&#xff0c;需要配置JAVA_HOME设置MAVEN自身的运行环境&#xff0c;需要配置MAVEN_HOME测试环境配置结果 MVN测试成功&#xff01;&#xff01;&#xff01; 二、本地仓库配置 Maven启动后&#xff0c;会自动保…

基于Amoeba读写分离(三十六)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 今天要学的是基于Amoeba读写分离。Amoeba是一个开源的关系型数据库管理系统&#xf…

Spark性能调优之数据序列化

前言 在使用Spark进行数据开发的时候,避不开的一个问题就是性能调优。网上一搜一大堆所谓的调优策略很多作者自己都不知所云,导致读者看了后只会更加困惑。我们在研究一个技术的时候第一手资料永远都请参考官网,官网对性能优化不一定是最全甚至最优,但是可以解决大部分问题…

向 Maven 中央仓库上传一个修改过的基于jeecg的autoPOI的 jar包记录

1、注册https://issues.sonatype.org/账号 下面就代表注册好了&#xff0c;同时提交的工单也通过了 2、这里主要是goupId 需要进行认证&#xff0c;需要到域名注册商近一个txt的解析&#xff0c;以便确保这个是你的 通过下面来验证你的域名信息&#xff0c;这里主要是上面的工…

面试题:说一说深拷贝和浅拷贝?

JavaScript中存在两大数据类型&#xff1a; 基本类型 和 引用类型 基本类型数据保存在在栈内存中 引用类型数据保存在堆内存中&#xff0c;引用数据类型的变量是一个指向堆内存中实际对象的引用&#xff0c;存在栈中 深拷贝和浅拷贝都只针对于引用类型。 一、 浅拷贝&#xff1…

Cpp7 — 继承和多态

继承 -------- 面向对象的三大特性之一 面向对象的三大特性&#xff1a;封装、继承、多态 封装&#xff1a;把数据和方法都封装在一起&#xff0c;想给你访问的变成共有&#xff0c;不想给访问的&#xff0c;写成私有。 继承&#xff1a;继承是类设计层次的复用 多态&#…

【AGI】Copilot AI编程辅助工具安装教程

1. 基础激活教程 GitHub和OpenAI联合为程序员们送上了编程神器——GitHub Copilot。 但是&#xff0c;Copilot目前不提供公开使用&#xff0c;需要注册账号通过审核&#xff0c;我也提交了申请&#xff1a;这里第一期记录下&#xff0c;开启教程&#xff0c;欢迎大佬们来讨论…