unittest 是python的单元测试框架,类似 java的 junit ,TestNG ,用法简单,可用做单元测试。
1. unittest 的简单用法
unittest提供了test cases、test suites、test fixtures、test runner相关的类,让测试更加明确、方便、可控。使用unittest编写用例,必须遵守以下规则:
1.测试文件必须先import unittest
2.测试类必须继承unittest.TestCase
3.测试方法必须以“test_”开头,python的文件名也最好以test开头
4.测试类必须要有unittest.main()方法
下面简述下unittest的用法:

运行后可以看到运行结果,通过和失败的用例。
unittest也支持命令行的方式运行,
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method
cd 到该文件目录下,然后输入 >python -m unittest test_Demo01

以下简要说明下unittest命令行的 常用参数,更多的可查看官方文档 https://docs.python.org/zh-cn/3/library/unittest.html#command-line-interface
-f, --failfast #当出现第一个错误或者失败时,停止运行测试。
-v, --verbose #更详细地输出结果。
-p, --pattern pattern #用于匹配测试文件的模式(默认为 test*.py ),这种格式的文件找出来执行
-t, --top-level-directory directory #指定项目的最上层目录(通常为开始时所在目录)
2. setUp ,tearDown 和执行顺序
unittest自带hook方法,setUp 和tearDwon ,setUpClass 和 tearDwonClass,可以理解成java 的构建函数和析构函数。setUpClass和tearDownClass 方法必须加 @classmethod 装饰器 。

运行结果如下,输出结果可以看出unittest的执行顺序,测试用例会按照字符顺序执行,如test_01 ,先于test_02:

但值得注意的是 unittest 有一个bug ,比如上面的例子,不做任何修改,多跑几次,随机会出现下面的通过(概率较低)

3. 断言
1. unittest的断言常用的有 assertEqual ,assertNotEqual ,assertTrue,assertFalse ,assertIn , ,assertNotIn ,assertIsNone ,assertIsNotNone等
2. 自定义断言信息 。以assertEqual 为例 , 默认为assertEqual(self, first, second, msg=None) ,可以自定义在两个数不相等的时候输出的信息assertEqual(self, first, second, msg="Not Equal")
4.跳过测试用例的方法
在执行用例的时候,并不需要每次都全部跑一次,unittest提供了跳过某些用例不执行的方法
@unittest.skip("don't run this case!"): 跳过执行
@unittest.skipIf(3<2,"don't run this case!"):跳过此用例如果
@unittest.skipUnless(3>2,"don't run this case!"): 跳过此用例,除非,例如

5. 用例加载和执行
unittest.main():使用她可以方便的将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以“test”命名开头的测试方法,并自动执行他们。执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。
unittest.TestSuite():unittest框架的TestSuite()类是用来创建测试套件的。
unittest.TextTextRunner():unittest框架的TextTextRunner()类,通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。
unittest.defaultTestLoader(): defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover。用法如下:
discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')



如果一个项目有很多的测试方法,多个文件目录

如何执行上面的用例 ?
1. 可以按照上面的方法,把各个文件的测试类加入到 unittest.TestSuite中,然后运行
(注意:一个py文件中可能有多个测试类,不同类有多个test方法)
2. discover 方法
1.discover 方法里面有三个参数:
--case_dir:这个是待执行用例的目录。
--pattern:这个是匹配脚本名称的规则,test*.py 意思是匹配 test 开头的所有脚本。
--top_level_dir:这个是顶层目录的名称,一般默认等于 None 就行了。
2.discover 加载到的用例是一个 list 集合,需要重新写入到一个 list 对象 testcase 里,
这样就可以用 unittest 里面的 TextTestRunner 这里类的 run 方法去执行。

上图中的 "." 是 case_dir pattern="*.py" 指后缀为py的文件都执行,通常用 "test*.py" ,top_level_dir=None默认为None
6.数据驱动ddt,参数化
下面是每个组件的简单介绍:
ddt.ddt:装饰类,用于unittest.TestCase子类的类装饰器。
ddt.data:添加到unittest.TestCase测试用例上的方法装饰器。
ddt.file_data(value):添加到unittest.TestCase测试用例上的方法装饰器。value应该是文件目录的路径。文件应该包含JSON编码的数据,可以是列表,也可以是dict。
如果文件中是列表,每个列表的值会作为测试用例参数,同时作为测试用例方法名后缀显示。
如果文件中是字典,字典的key会作为测试用例方法的后缀显示,字典的值会作为测试用例参数。
ddt.unpack:
传递的是复杂的数据结构时使用。比如使用元组或者列表,添加unpack之后,ddt会自动把元组或者列表对应到多个参数上。

参数化数据放在yml 或json 文件中,与代码分离。如在当前目录下新建一个ddt_file.json ,里面输入数据

如图,这里新建了2条用例,均有用例名称 每个json的值里面是参数化的数据
代码修改如下:

再跑一次,此时可以看到跑的用例数和参数化的数据一致

另外一种参数化方法 (参考网上例子的)

7. 测试报告
批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成 HTML 格式的。
unittest 里面是不能生成 html 格式报告的,需要导入一个第三方的模块:HTMLTestRunner
1. 这 个 模 块 下 载 不 能 通 过 pip 安装了,只能下载后手动导入,下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html
下载后解压到项目下,如果放入到项目目录下import 时候找不到 ,可以在 python安装目录\lib 下面放一份,如在F:\python3.5.2\Lib\HTMLTestRunner_PY3
在run_all_case.py

HTMLTestRunner的参数说明如下:
--stream:测试报告写入文件的存储区域
--title:测试报告的主题
--description:测试报告的描述
查看报告详情
生成的report.html 用浏览器打开查看

失败的用例点击【失败】可以查看失败的详情

2.为了生成带中文描述的测试用例,可以在 case 中添加注释,如在脚本添加如下注释:

重新跑一次测试用例,即可看到中文注释

网友评论