unittest 统计测试执行case总数,成功数量,失败数量,输出至文件,生成一个简易的html报告带饼图
这是一个Python的单元测试框架的示例代码,主要用于执行测试用例并生成测试报告。其中,通过unittest模块创建主测试类MainTestCase,并加载其他文件中的测试用例,统计用例的执行结果并将结果写入文件,最后生成一个简单的测试报告html页面。
在执行测试时,可以根据需要添加更多的测试文件和测试用例,在自定义CustomTextTestResult类中重写addSuccess和addFailure方法,获取用例的执行结果,并在统计成功和失败的用例数量时进行累加。将用例执行成功和失败的信息分别保存到success_cases和failure_cases列表中,最后将结果写入文件。
在生成测试报告时,利用HTML和CSS语言生成一个表格结构的页面,并将测试结果以文本和图表的形式展示出来。在页面中使用了一些JavaScript代码来计算成功和失败的百分比,并将其以饼状图的形式呈现出来。最终,将html代码写入到文件中,生成测试报告。
main.py
import unittest
import timeclass MyTestcase(unittest.TestCase):def test_1(self):print('main_test_1')self.assertEqual(2 - 2, 4)def test_2(self):print('main_test_2')self.assertEqual(2 - 2, 4)def test_3(self):print('test_3')time.sleep(2)self.assertEqual(2 + 2, 4)def test_4(self):print('test_4')self.assertEqual(2 - 2, 4)def test_5(self):print('test_5')self.assertEqual(2 + 2, 4)def test_6(self):print('test_6')self.assertEqual(2 + 2, 4)def test_7(self):print('test_7')self.assertEqual(2 + 2, 4)def test_8(self):print('test_8')self.assertEqual(2 + 3, 4)
Testcase2.py
import unittestclass TestcaseGo(unittest.TestCase):def test_1(self):print('TestcaseGo_test_1')self.assertEqual(2 - 2, 4)def test_2(self):print('TestcaseGo_test_2')self.assertEqual(2 - 2, 4)def test_3(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_4(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_5(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_6(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_7(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_8(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_9(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_10(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_11(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_12(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_13(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_14(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_15(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_16(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_17(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_18(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_19(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_20(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_21(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_22(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_23(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)def test_24(self):print('TestcaseGo_test_3')self.assertEqual(2 + 2, 4)
run.py
import unittest
import datetime# 创建主测试类
class MainTestCase(unittest.TestCase):passif __name__ == '__main__':# 统计测试用例执行开始时间today1 = datetime.date.today()current_time1 = datetime.datetime.now().time()# print("执行开始时间:" + str(today1) +" "+ str(current_time1))# 创建测试加载器loader = unittest.TestLoader()# 加载其他Python文件中的测试用例并添加到主测试类中test_cases = [loader.loadTestsFromName('main.MyTestcase'),loader.loadTestsFromName('Testcase2.TestcaseGo')# 添加更多的测试文件和测试用例]suite = unittest.TestSuite(test_cases)suite.addTests(loader.loadTestsFromTestCase(MainTestCase))# 计算总用例数量total_count = suite.countTestCases()# 定义全局的成功、失败和总数计数变量success_count = 0failure_count = 0# 保存执行成功的用例和执行失败的用例success_cases = []failure_cases = []# 重写run()方法,获取用例的执行结果class CustomTextTestResult(unittest.TextTestResult):def addSuccess(self, test):global success_countsuccess_count += 1success_cases.append(str(test))super().addSuccess(test)def addFailure(self, test, err):global failure_countfailure_count += 1failure_cases.append(str(test))super().addFailure(test, err)# 创建测试运行器并运行测试runner = unittest.TextTestRunner(verbosity=2, resultclass=CustomTextTestResult)result = runner.run(suite)# 将结果写入文件,指定编码格式为UTF-8with open("test_result.txt", "w", encoding="utf-8") as file:file.write(f"成功的用例数量: {success_count}\n")file.write(f"失败的用例数量: {failure_count}\n")file.write(f"总用例数量: {total_count}\n")file.write("\n执行成功的用例:\n")for case in success_cases:file.write(case + "\n")file.write("\n执行失败的用例:\n")for case in failure_cases:file.write(case + "\n")print("测试结果已写入文件 test_result.txt")# print(total_count)# print(success_count)# print(failure_count)# print(success_cases)# print(failure_cases)# 生成一个简单的测试报告html页面def html_report(today1, current_time1, total_count, success_count, failure_count, success_cases, failure_cases):# 用例总数量、成功数量、失败数量、百分比Success_Rate = (success_count / total_count) * 100failure_Rate = (failure_count / total_count) * 100# print(int(Success_Rate))# print(int(failure_Rate))Success_Rate_text = str(int(Success_Rate)) + '%'failure_Rate_text = str(int(failure_Rate)) + '%'# print(Success_Rate_text)# print(failure_Rate_text)Success_Rate_text_b = '{'+str(Success_Rate)+'}%'# 拼接元素# text_content1 = "\n".join(success_cases)# text_content2 = "\n".join(failure_cases)test_cases_with_br = [f"{case}<br/>" for case in success_cases]# 将带有<br>标签的元素连接成一个字符串text_content1 = "".join(test_cases_with_br)test_cases_with_br = [f"{case}<br/>" for case in failure_cases]# 将带有<br>标签的元素连接成一个字符串text_content2 = "".join(test_cases_with_br)text_content1 = text_content1text_content2 = text_content2# 统计测试用例执行时间today2 = datetime.date.today()current_time2 = datetime.datetime.now().time()# print("执行结束时间:" + str(today2) + str(current_time2))time_diff = datetime.datetime.combine(datetime.date.min, current_time2) - datetime.datetime.combine(datetime.date.min, current_time1)strat_time = str(today1) + " " + str(current_time1)over_time = str(today2) + " " + str(current_time2)# 测试报告html源码report = """<!DOCTYPE html><html><head><meta charset="utf-8"><title>表格示例</title><style>""" \+ \""".status-labels {display: flex;justify-content: space-between;margin-bottom: 10px;}.status-label {display: flex;align-items: center;text-align: center;flex-direction: column;}.status-color {width: 20px;height: 20px;margin-right: 5px;align-items: center;}.pie-chart {width: 200px;height: 200px;border-radius: 50%;background: linear-gradient(to right, green 50%, red 0);transform: rotate(-90deg);margin: 20px auto;} """ + """th, td {{text-align: center;padding: 10px;vertical-align: top;}}table {{margin-left: auto;margin-right: auto;border-collapse: collapse;margin: auto;}}</style></head><body><br/><br/><table border="1"><thead><th>成功的用例数量</th><th>成功的用例占比</th><th>失败的用例数量</th><th>失败的用例占比</th><th>总用例数量</th></thead><tbody><tr><td>{success_count}</td><td>{Success_Rate_text}</td><td>{failure_count}</td><td>{failure_Rate_text}</td><td>{total_count}</td></tr></tbody></table><br/><table border="1"><thead><tr><th>执行开始时间</th><th>执行结束时间</th><th>执行总耗时</th></tr></thead><tbody><tr><td>{strat_time}</td><td>{over_time}</td><td>{time_diff}</td></tr></tbody></table><br/><br/><table id="my-table"><thead><tr><th><div class="status-color" style="background-color: #336699;"></div></th><th>成功</th><th><div class="status-color" style="background-color: #bf242a;"></div></th><th>失败</th></tr></thead><tbody></tbody></table><div class="pie-chart"></div><br/><table border="1"><thead><tr><th>执行成功的用例</th><th>执行失败的用例</th></tr></thead><tbody><tr><td>{text_content1}</td><td>{text_content2}</td></tr></tbody></table><br/><br/>""".format(time_diff=time_diff, strat_time=strat_time, over_time=over_time, total_count=total_count,success_count=success_count, Success_Rate_text=Success_Rate_text, failure_count=failure_count,failure_Rate_text=failure_Rate_text, text_content1=text_content1, text_content2=text_content2) \+ \"""<script>// 获取饼图元素var pieChart = document.querySelector('.pie-chart');// 设置饼图的背景渐变色pieChart.style.background = `conic-gradient(#336699 ${Success_Rate_text}, #bf242a 0)`;</script>""".format(Success_Rate_text=Success_Rate_text_b) + """</body></html>"""# ${successPercentage}%# $81%print(report)with open("html_result.html", "w", encoding="utf-8") as file:file.write(report)print("测试报告生成成功!")html_report(today1, current_time1, total_count, success_count, failure_count, success_cases, failure_cases)# html_report(total_count, success_count, failure_count, success_cases, failure_cases)


相关文章:
unittest 统计测试执行case总数,成功数量,失败数量,输出至文件,生成一个简易的html报告带饼图
这是一个Python的单元测试框架的示例代码,主要用于执行测试用例并生成测试报告。其中,通过unittest模块创建主测试类MainTestCase,并加载其他文件中的测试用例,统计用例的执行结果并将结果写入文件,最后生成一个简单的…...
推荐一款功能强大的在线文件预览工具-kkFileView
程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…...
【Linux】磁盘阵列,了解不同raid的特点
一、raid和阵列卡介绍 1、什么是磁盘阵列: 磁盘阵列是利用虚拟化存储技术把很多块独立的磁盘组合成一个容量巨大的磁盘组,利用个别磁盘提供数据所产生加成效果提升整个磁盘系统效能。利用这项技术,将数据切割成许多区段,分别存放…...
Go 语言初探:从基础到实战
1.Go概述 程序是一段计算机指令的有序组合。程序算法数据结构。任何程序都可以将模块通过三种基本的控制结构(顺序、分支、循环)进行组合来实现。 Go(也称为Golang)是一种由Google开发的开源编程语言。设计目标是使编程更简单、…...
Kotlin文件和类为什么不是一对一关系
在Java中,一个类文件的public类名必须和文件名一致,如何不一致就会报异常,但是在kotlin的文件可以和类名一致,也可以不一致。这种特性,就跟c有点像,毕竟c的.h 和 .cpp文件是分开的。只要最终编译的时候对的…...
Kubernetes实战(四)-部署docker harbor私有仓库
1 Docker原生私有仓库Registry 1.1 原生私有仓库Registry概述 Docker的仓库主要分两类: 私有仓库公有仓库 共有仓库只要在官方注册用户,登录即可使用。但对于仓库的使用,企业还是会有自己的专属镜像,所以私有库的搭建也是很有…...
IDEA JAVA项目 导入JAR包,打JAR包 和 JAVA运行JAR命令提示没有主清单属性
一、导入JAR包 1、java项目在没有导入该jar包之前,如图:2、点击 File -> Project Structure(快捷键 Ctrl Alt Shift s),点击Project Structure界面左侧的“Modules”如图:3.在 “Dependencies” 标签…...
c#输入和输出
第一个c#程序 /* c#在编译时首先编译为通用中间语言(IL代码),并且将其存在程序集中 c#的程序集包括扩展名为.exe的可执行文件和扩展名为.dll的可供其他程序调用的库文件c#在执行时首先将程序集加载到CLR中,然后通过即时编译器编译…...
设置区块链节点输出等级为警告级,并把日志存储阈值位100MB并验证;
题目 获取指定区块链节点输出等级为警告级,并设置日志存储阈值位100MB并验证; 操作步骤 1.切换目录 cd nodes/127.0.0.1/node0 2.打开配置文件并修改 vim config.ini warn:警告...
perl列表创建、追加、删除
简介 perl 列表追加元素 主要是通过push和unshift函数来实现。其中,push是追加到列表尾,unshift是追加到列表头。 perl列表删除元素 主要是通过pop和shift函数来实现。其中,pop是从列表尾删除一个元素, shift是从列表头删除一…...
leetcode刷题日记:94. Binary Tree Inorder Traversal(二叉树的中序遍历)
给出二叉树的根结点,返回二叉树的中序遍历序列。 二叉树的中序遍历序列是先遍历左子树再遍历根结点然后再遍历右子树,在遍历左子树是这个结点是左子树的根结点,左子树有左子树和根结点右子树,也就是说在遍历的时候我们要递归遍历。…...
【漏洞复现】Aapache_Tomcat_AJP协议_文件包含漏洞(CVE-2020-1938)
感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 说明内容漏洞编号CVE-2020-1938漏洞名称Aapache_Tomcat_AJP文件包含漏洞漏洞评级高…...
RabbitMQ消息可靠性投递
RabbitMQ消息投递的路径为: 生产者 —> 交换机 —> 队列 —> 消费者 在RabbitMQ工作的过程中,每个环节消息都可能传递失败,那么RabbitMQ是如何监听消息是否成功投递的呢? 确认模式(confirm)可以监…...
汽车网络安全渗透测试概述
目录 1.汽车网络安全法规概述 1.1 国外标准 1.2 国内标准 2.汽车网络安全威胁分析 2.1 汽车网络安全资产定义 2.2 汽车网络安全影响场景及评级示例 3.汽车网络安全渗透测试描述 3.1 参考法规 3.2 渗透测试内容 4.小结 1.汽车网络安全法规概述 近年来,汽车…...
NOIP2023模拟14联测35 charlotte
题目大意 给你一棵有 n n n个节点的树,并用 01 01 01串告诉你哪些节点上有棋子(恰好一棵)。 你可以进行若干次操作,每次操作可以将两颗距离至少为 2 2 2的棋子向彼此移动一步。 问能否通过若干次操作使得所有的棋子都在一个点上…...
绿色科技和可持续发展技术
一、绿色科技和可持续发展技术的定义 绿色科技和可持续发展技术是指那些利用可再生资源、减少环境污染和促进可持续发展的技术。这些技术不仅可以提高人们的生活质量,同时也可以减少对自然环境的破坏,并且能够为未来的可持续发展提供保障。 二、绿色科…...
建链时,please install openssl! use “openssl version“ command to check.
please install openssl! use “openssl version” command to check. 但是我已经安装了 编辑build_chain.sh文件 也可以用vi或者gedit命令 将 [ ! -z “ ( o p e n s s l v e r s i o n ∣ g r e p 1.0.2 ) " ] ∣ ∣ [ ! − z " (openssl version | grep 1.0.2)…...
“Redis与Spring整合及缓存优化“
文章目录 引言1. Spring整合Redis1.1. 为什么选择Redis作为缓存解决方案?Redis的特点和优势Redis与传统关系数据库的对比 1.2. Spring与Redis整合的基本步骤 2. Redis注解式缓存2.1. Spring提供的缓存注解介绍2.2. 使用注解实现方法级别的缓存 3. Redis的击穿、穿透…...
腾讯云3年云服务器价格及购买教程
腾讯云作为国内领先的云计算服务提供商,提供了多种优惠的云服务器套餐,以满足不同用户的需求,本文将详细介绍腾讯云3年云服务器价格及购买教程,新老用户均可购买! 1、活动页面:传送门>>> 2、进入…...
cortex-A7核 中断实验(按键中断实验)
1.选择按键触发方式 下降沿 2.解决消抖的方法 1)ARM中:延时消抖 2)linux驱动开发:定时器函数 3.框图 内部流程框图: 需要RCC GPIO EXTI GIC章节 中断触发流程: 4.RCC 章节 1)使能GPIOF组 …...
批量获取 Amazon 商品信息的优化方案
在跨境电商运营、竞品分析与选品决策中,批量、稳定、合规地获取 Amazon 商品信息是核心刚需。直接高频爬取易触发 IP 封禁、验证码拦截与账号风险,单接口调用效率低、成本高。本文从合规选型、效率优化、反爬规避、架构落地四个维度,提供一套…...
告别繁琐配置:用Docker一键搞定RKNN模型转换环境(Windows/Linux/Mac通用)
跨平台RKNN模型转换实战:Docker化环境搭建与高效部署指南 当AI开发者需要在不同设备上部署模型时,环境配置往往成为最耗时的环节。特别是在使用Rockchip NPU进行边缘计算时,传统的虚拟机配置、交叉编译等方法既繁琐又容易出错。本文将介绍如何…...
Spring Boot 实现网络限速:让流量“收放自如”
Spring Boot 实现网络限速:让流量“收放自如” 一、为啥要网络限速? 在当今这个数字化时代,网络服务就像我们生活中的水电一样不可或缺,而网络限速则是保障这些服务稳定、高效运行的关键一环。它能确保在各种复杂的网络环境下&…...
生成单颗10mm级配的cluster骨料
PFC5.0代码,可以破碎的cluster,可模拟碎石、矿渣混凝土材料,ball与cluster颗粒,单轴压缩实验,内涵声发射事件数代码,分析统计ball与ball直接的裂纹数目,cluster内部破碎的裂纹数目上周帮同门调P…...
ABAP - SMW0实现Excel模板下载与数据上传解析全流程指南(附完整代码)
1. 为什么需要Excel模板下载与上传功能 在企业级应用开发中,Excel模板的下载与上传功能几乎是标配。想象一下这样的场景:财务部门需要每月收集各部门的预算数据,如果让每个部门直接在SAP系统里录入,操作复杂且容易出错。而提供一个…...
如何选择ComfyUI-FramePackWrapper的模型加载方案?从技术选型到场景适配全解析
如何选择ComfyUI-FramePackWrapper的模型加载方案?从技术选型到场景适配全解析 【免费下载链接】ComfyUI-FramePackWrapper 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-FramePackWrapper 在AI视频生成工作流中,模型加载是影响效率与稳…...
咱们今天聊点硬核但有趣的东西——用纳米级乐高积木(二氧化钛超表面)玩转光漩涡。想象一下,你手上有把能操控光波前形状的万能钥匙,这就是超表面的魅力所在
FDTD模型:基于超表面的完美涡旋光案例。 宽带任意阶 完美涡旋光束 介绍:全介质超表面实现完美矢量涡旋光束生成和完美庞加莱球生成,完美矢量涡旋光束不随拓扑荷的变化而变化,同时满足矢量光场的偏振变化,主要用于光学加密等领域&a…...
避坑指南:Unreal导航网格NavMesh生成与Agent属性设置的5个常见误区
Unreal引擎导航系统避坑指南:NavMesh生成与Agent配置的5个关键误区 在Unreal引擎中构建可靠的AI寻路系统时,许多开发者常陷入相似的陷阱。当AI角色频繁卡在门槛边缘、拒绝攀爬斜坡或选择匪夷所思的绕路路线时,问题往往不在于代码逻辑…...
WebDAV网盘横向评测:从个人备份到多端同步的实战指南
1. WebDAV网盘入门:为什么你需要它? 刚接触WebDAV时,我和大多数人一样疑惑:明明有那么多现成的网盘,为什么还要折腾这个?直到有次出差,急需修改存放在某商业网盘里的设计方案,却发现…...
洛雪音乐音源项目终极指南:如何免费获取全网高品质音乐资源
洛雪音乐音源项目终极指南:如何免费获取全网高品质音乐资源 【免费下载链接】lxmusic- lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/gh_mirrors/lx/lxmusic- 你是否曾为寻找免费的高品质音乐资源而烦恼?或者厌倦了在多个音…...
