我们日常测试中经常需要将测试结果/报告予以公示/推送,而一份清晰且可读性强的测试报告可以让人更快速的了解整个测试结果。在自动化测试过程中,能够快速生成清晰、全面、可视化的测试报告 (如 HTML 报告),无疑也是一项可观的效率提升。
目前主流的生成测试报告的第三方库(如:HTMLTestRunner、Allure 等)使用起来都各有利弊。本文介绍基于 unittestreport 框架快速生成清晰可视化的 HTML 测试报告方法,该框架同时兼顾 unittest 和 pytest 框架,支持多种报告风格样式切换,具备实用、美观、共享方便等特性。
unittestreport 是基于 unittest 开发的的一个开源的功能扩展库。最初只是计划开发一个 unittest 生成 html 测试报告的模块,所以起名叫做 unittestreport。
unittestreport 在版本迭代中提供了越来越丰富的功能,目前已支持 HTML 报告生成/数据驱动/失败重运行/多线程并发/测试结果推送等功能。
使用过程中,可以直接通过 pip 安装 unittestreport:
unittest 框架:
pip install unittestreport
pytest 框架:
pip install pytest-testreport
unittestreport 中封装了一个 TestRunner 类,用来代替 unittest 中的 TextTestRunner 执行测试用例,执行完测试用例之后会自动生成 HTML 测试报告。
用例执行过程遵循: 加载测试用例->创建测试程序->运行用例->生成报告过程。最简单的调用过程如下:
TestRunner 类创建测试报告时,可以指定参数自定义报告内容:
● suite:测试套件,测试用例集
● filename:测试报告文件名称,缺省值:report.html
● report_dir:测试报告存放路径,缺省值:./reports
● tester:测试人员名称息,缺省值:测试员
● desc:测试报告描述,缺省值:xx 项目测试生成的报告
● title:测试报告标题,缺省值:测试报告
● templates:生成测试报告的模板类型,缺省值:1,取值范围:[1,2,3]
unittestrepor 中通过指定不同的 templates 取值来设置测试报告模板,用以支持不同风格的测试报告样式:
● 模板 1(templates =1)报告样式
此为缺省的报告样式。该模板更直观的展示了通过率
● 模板 2(templates =2)报告截图
此模板还统计了历史数据,能更直观的反映出相同用例在每次迭代过程中的通过率。
模板统计的历史数据保存在 reports 目录下的 history.json 文件中,在获取报告数据方法 TestRunner.get_reports() 中通过调用方法_handle_history_data() 提取出历史数据:
● 模板 3(templates =3)报告截图
该模板即为 BeautifulReport 报告样式。
● 高频功能
unittestreport 在数次版本迭代中逐步丰富了 unittest 框架原生不具备的但测试中经常需要或用到的功能(如:数据驱动、并行测试、结果推送等)。
● 数据驱动
数据驱动的目的是将测试数据和用例逻辑进行分离,提高代码重用率及用例的维护。
unittestreport.dataDriver 模块使用 ddt 进行数据驱动,支持 list/json/yaml 三种方式生成测试用例。
在实际使用过程中,需要通过@ddt装饰测试用例类对象,并在具体的用例方法中引用@list_data/@json_data/@yaml_data 进行驱动:
unittestreport 重新封装了 TestRunner 类,使用传参调用 TestRunner.run() 方法实现多线程运行和失败重跑机制
● thread_count:指定运行用例时开启的线程数量
● count:指定用例失败重跑次数
● interval:指定每次重跑的时间间隔,秒
需要注意的是,unittestreport 中多线程并发执行时,为解决用例执行的顺序问题,默认以测试类为单位开启线程执行,即:
● 同一个测试类中的用例,在执行的过程中执行的先后顺序能够得到保证
● 不同的测试类在执行的过程中是一个并发执行状态,执行的先后顺序是不确定的
unittestreport 框架基于 SMTP 协议实现邮件发送,通过 TestRunner 类 send_email() 方法,执行完测试用例调用即可推送报告
解决邮件发送 SSLError 错误
unitestreport 框架是基于 SMTP 协议实现邮件发送的,而常用的 SMTP 方式有 3 种:
①.明文传输:端口号 25
②.SSL 加密:端口号 465,通信过程加密,邮件数据安全
③.TLS 加密:端口号 587,通信过程加密,邮件数据安全,需要先建立 SSL 连接。
按现有 unittestreport 源码实现,仅支持 465 端口和 25 端口,当采用端口 port=587 进行加密邮件发送时会报错:
基于上述现象,结合实际需求必须使用 587 端口,在使用过程中对 unittestreport 源码进行了优化,用以支持 587 端口邮件发送,具体实现如下:
uinttestreport 框架本身是不支持 HTMLTestRunner 样式的报告的,导致之前项目使用 HTMLTestRunner 框架生成的报告,替换为 unittestreport 样式后存在不兼容现象。
基于上述问题,在实际项目中对 unittestreport 框架进行了 HTMLTestRunner 报告兼容处理,主要包括:
①.整合 HTMLTestRunner 框架源码到 unittestreport,实现两种报告样式的快速互切。
②.优化了 HTMLTestRunner 部分源码,兼容 unittestreport 框架的 TestRunner.run() 方法。
整合 HTMLTestRunner 框架
unittestreport 框架兼容 HTMLTestRunner 框架需要增加相关的模板风格,由于 HTMLTestRunner 框架无独立的模板文件 (templates.html),需要将 HTMLTestRunner.py 进行源码整合。具体过程如下:
①.拷贝 HTMLTestRunner.py(已修改为支持 python3)至 uinttestreport 源码 core 目录
②.修改 unittestreport 的init.py 文件,增加导入 HTMLTestRunner 模块代码
③.执行主流程中引入 HTMLTestRunner 模块
④.并执行测试用例,生成测试报告
扩展 TestRunner.run() 方法
HTMLTestRunner 框架调用 run 方法必参测试套件 suite,这与 unittestreport 框架空参调用 run 方法存在差异,为了更方面代码维护实现两者互切,对 HTMLTestRunner 源码进行了部分优化,具体实现如下:
①.更新 HTMLTestRunner.py 的构造方法init():
a).添加测试套件 suite 参数,并填充缺省值用以兼容原始构造方法
b).支持在构造对象时传递测试套件 suite,并兼容原始构造方法不传递测试套件场景
②.更新 HTMLTestRunner.py 的 run(),确保不传递测试套件 suite 时,也能通过上述构造函数拿到测试套件继续执行:
a).入参 test 添加缺省值,兼容不传递测试套件 suite 场景
b).解决不传递测试套件 suite 时,也能从构造方法中提取
这样既兼容了原有 HTMLTestRunner 调用 run() 方法传参方式,也扩展了 run 方法,与 unittestreport 的 TestRunner.run() 的调用方式保持一致
基于此,使用 unittestreport 框架生成 HTMLTestRunner 风格可以有 2 种调用方式:
本文基于 unittestreport 框架介绍了如何快速生成清晰可视化的 HTML 测试报告方法,并基于实践应用对框架进行了功能优化和扩展。