UnitTest 测试框架
🍰 一款Python自带的单元测试框架,适用于单元测试,还可用于Web、Appium、接口自动化测试用例的开发与执行等。
1 框架核心
- 框架核心
- TestCase:测试用例。
- 一个测试用例就是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
- 包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的销毁(tearDown)。
- TestSuite:测试套件,即多个测试用例集合在一起,TestSuite可以嵌套TestSuite。
- TextTestRunner:执行测试用例,包括执行TestSuite或TestCase中的方法。
- TestLoader:批量执行测试用例(可搜索指定文件夹内指定字母开头的模块)。
- Fixture:固定装置(两个固定函数,一个初始化时使用,一个结束时使用,即测试环境的搭建和销毁)。
- TestCase:测试用例。
1-1 TestCase
1 |
|
1-2 TestSuite
1 |
|
1-3 TestLoader
1 |
|
1-4 加载与套件
- 加载与套件
- TestLoader用于加载测试用例,而TestSuite用于组织和管理测试用例。
- 加载用例方法
discover("file_path", pattern)
·······································从指定目录中加载用例loadTestsFromModule(test_module)
·····································模块加载单个测试用例loadTestsFromTestCase(TestCaseClass)
·································TestCase类加载单个测试用例loadTestsFromName('test_module.TestCaseClass')
·······················从完整路径加载单个测试用例loadTestsFromNames(['test_module.TestCaseClass1', 'test_module.TestCaseClass2'])
···加载多个用例
- 添加用例方法:添加单个用例可以使用
suite.addTest()
,添加多个用例可以使用suite.addTests()
。 discover()
会自动扫描指定目录及其子目录中的测试文件,递归地发现并加载测试用例,无需逐个指定。loadTestsFromXXX()
需要显式地指定要加载的测试用例或模块,适合于手动指定加载特定的用例或模块。makeSuite()
适用于已经定义好的测试类,而loadTestsFromXXX()
适用于需要动态加载测试用例的情况。
1 |
|
1-5 测试脚手架
- 测试脚手架
- 测试脚手架即Fixture,一种代码结构,可以在测试用例执行前后自动调用指定的函数。
- 方法级别:每个测试方法执行前都会执行
setUp()
,执行之后都会执行tearDown()
。 - 类级别:每个类执行前执行一次
setUpClass()
,执行后执行一次tearDownClass()
。 - 模块级别:模块执行前执行一次
setUpModule()
,模块执行后执行一次tearDownModule()
。
1 |
|
2 结果断言
- 结果断言
assertIsNone(obj, msg=None)
················验证obj是None,不是则failassertIsNotNone(obj, msg=None)
·············验证obj不是None,是则failassertIn(member, container, msg=None)
······验证container是否包含memberassertNotIn(member, container, msg=None)
···验证container是否不包含memberassertTrue(expr, msg=None)
·················验证expr是true,如果为false则failassertFalse(expr, msg=None)
················验证expr是false,如果为true则failassertEqual(expected, actual, msg=None)
····验证expected==actual
,不等则failassertNotEqual(first, second, msg=None)
····验证first!=second
,如果相等则fail
1 |
|
3 跳过用例
- 跳过用例
@unittest.skip(reason)
····················无条件跳过@unittest.skipIf(condition, reason)
·······当condition为True时跳过@unittest.skipUnless(condition, reason)
···当condition为False时跳过
1 |
|
4 数据驱动
- 数据驱动
- 指数据参数化,即ddt(data-driver tests),以数据来驱动整个测试用例的执行。
- 代码和数据分离,避免冗余,不写重复的代码逻辑,安装:
pip install ddt
。
1 |
|
4-1 txt
1 |
|
- Txt文件驱动:一行表示一组数据。
1 |
|
4-2 csv
1 |
|
(1) test_csv1.py
1 |
|
(2) test_csv2.py
1 |
|
4-3 json
1 |
|
@data()
中的*
是传入元组,如果是**
,则传入字典。
1 |
|
4-4 yaml
1 |
|
file_data()
装饰器:可以直接读取yaml和json文件。
1 |
|
4-5 excel
1 |
|
- Excel文件驱动:需要使用到openpyxl库,安装库
pip install openpyxl
。
1 |
|
5 日志操作
- 日志操作
- 记录测试用例的执行情况,排查错误,使用Python自带的logging模块。
logging.debug()
········调试日志,诊断问题时使用,最详细的日志logging.info()
·········普通日志,确定程序是否按照预期的流程执行logging.warning()
······警告日志,可能会出现的问题,程序仍可执行logging.error()
········错误日志,某些功能软件可能无法正确地执行logging.critical()
·····严重错误,表明程序本身可能无法再继续执行
5-1 导出日志
1 |
|
5-2 日志处理
- 日志处理
- 应用程序中的不同部分通过获取相同的日志记录器实例来记录日志。
- 日志记录器(Logger)创建日志消息,并将日志消息传递给已配置的日志处理器(Handler)。
- 日志处理器将日志输出到指定的终端,同时应用格式化器(Formatter)对日志进行格式化。
- 格式化后的日志消息以统一格式输出到指定的终端,以便进行跟踪和诊断应用程序的行为。
1 |
|
6 测试报告
- 测试报告
- Text测试报告:使用
unittest.TextTestRunner()
方法生成Text类型的测试报告。 - 自带的测试报告:Pycharm执行结果Run中的
Export Test Results
进行设置生成。 - XTestRunner测试报告,使用命令安装XTestRunner第三方库:
pip install XTestRunner
。 - BeautifulReport测试报告,需命令安装BeautifulReport库:
pip install BeautifulReport
。 - HTMLTestRunner测试报告,需要手动下载并修改HTMLTestRunner.py文件内容,再放入Lib中。
- Text测试报告:使用
6-1 Text测试报告
1 |
|
6-2 XTestRunner
1 |
|
6-3 BeautifulReport
1 |
|
6-4 HTMLTestRunner
- 命令安装HTMLTestRunner第三方库会报错,该库由Python2编写,没有版本更新。
1 |
|
- 下载“HTMLTestRunner.py (0.8.2)”后,将文件放入Python安装路径的Lib目录下。
- 修改HTMLTestRunner.py文件内容,可参考文章“Python3使用HTMLTestRunner”。
1 |
|
7 配置解析
- 配置解析
- ini:Initialization,是Windows系统常见的配置文件格式,使用简单的键值对结构来存储配置信息。
- conf:Configuration,通常用于Unix或Linux系统中,也是文本文件,用于存储应用程序的配置信息。
- cnf:Configuration,通常用于MySQL数据库中,也是文本文件,用于存储数据库服务器的配置信息。
- cfg:Configuration,通用的配置文件格式,采用了不同的结构和语法,存储各种应用程序的配置信息。
- yaml:与yml同种格式,扩展名不同,是一种可读的数据序列化标准,使用缩进和换行来表示数据结构。
7-1 ini格式
1 |
|
7-2 ini解析
1 |
|
7-3 yml解析
1 |
|
(1) 数组格式
1 |
|
(2) Map对象
1 |
|
8 项目框架
- 项目框架
- 单例模式:导入模块时会执行模块所在的
__init__.py
文件,将公用模块放入文件代码中,以实现单例模式。 - 配置文件封装:能处理多种类型的配置文件,返回值数据结构一致,简单功能封装成函数,复杂功能封装成类。
- 变量配置:项目根目录下单独使用一个Python文件,在其中定义配置信息,其他模块直接引用效率更高更直观。
- 单例模式:导入模块时会执行模块所在的
8-1 基本框架
1 |
|
(1) main.py
1 |
|
(2) test_api.py
1 |
|
(3) test_api.csv
1 |
|
(4) log_output.py
1 |
|
(5) http_request.py
1 |
|
8-2 单例模式
1 |
|
(1) __init__.py
1 |
|
(2) test_api.py
1 |
|
8-3 配置封装
1 |
|
(1) main.py
1 |
|
(2) conf.ini
1 |
|
(3) conf.yaml
1 |
|
(4) test_api.py
1 |
|
(5) __init__.py
1 |
|
(6) config_func.py
1 |
|
(7) config_class.py
1 |
|
8-4 变量配置
1 |
|
(1) main.py
1 |
|
(2) settings.py
1 |
|
(3) test_api.py
1 |
|
(4) __init__.py
1 |
|
UnitTest 测试框架
https://stitch-top.github.io/2023/07/23/ce-shi-kuang-jia/tf04-unittest/tf01-unittest-ce-shi-kuang-jia/