一、简介
unittest是python自带的单元测试框架
主要有以下几个概念:
1、test fixture:初始化和清理 测试数据、以及环境,比如在用例执行前创建临时文件和文件夹,,或者代理数据库、目录,又或者启动服务器进程
最简单的实现方式是通过自定义下面的2个方法:
- TestCase.setUp():在每个测试方法运行之前都会运行一次,适合为每个用例都初始化一遍数据,有几个以test开头的方法就执行几次
- TestCase.tearDown():在每个测试方法运行之后都会运行一次,适合为每个用例都清理一遍数据
2、test case:测试用例
所有的测试类都必须直接或间接的继承自unittest.TestCase类
3、test suite:用例集合,组合起来批量执行
4、test runner:运行用例并返回结果,可以使用图形界面、文本界面,或者返回一个特殊值来指示执行测试的结果
注意点:测试用例中方法名需要以test开头,不然是不会被test runner执行的
二、用法
前置条件:在创建测试用例之前需要导入unittest
1个测试用例类下面可以有多个测试方法(test)或者叫做测试点,如下就有3个用例,其中TestStringMethods继承了unittest.TestCase,实际工作中我们会写test_case1、test_case2......
import unittest
class TestStringMethods(unittest.TestCase): # 定义测试类
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_spilt(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
with self.assertRaises(TypeError):
s.split(2)
if __name__ == "__main__":
unittest.main()
# suite = unittest.TestLoader().loadTestsFromTestCase(TestStringMethods)
# unittest.TextTestRunner(verbosity=2).run(suite)
断言
在开发一个程序的时候,与其让它运行时崩溃,不如在它出现错误条件时就返回错误,所以断言是测试用例的核心,常见的就是assert断言,一般来说每个测试方法里都必须有断言
比如判断接口通不通,返回值对不对,错误描述信息是否一致等等,我常用的就是下面2种:
- assertEqual(first, second, msg=message)
- assertNotEqual(first, second, msg=message)
断言第一个参数和第二个参数是否相等,如果相等,则输出OK信息,若不相等则测试失败。其中 msg 为可选参数,用于输出测试失败时提示信息。
self.assertEqual(response.get('success'), True)
self.assertEqual(form.external_id.data, response_external_id, msg=message.to_str('业务逻辑错误'))
- 调用assertEqual()来检查预期结果;
- assertTrue()或assertFalse()来验证条件;
- assertRaises()来验证是否引发了特定的异常。
使用上述方法而不是assert语句,是为了测试运行程序可以累积所有测试结果并生成报告。
其余用法可参考博客园上的一篇文章 https://www.cnblogs.com/feiyueNotes/p/7788995.html
运行case
全局:unittest.main
或者下面的
suite = unittest.TestLoader().loadTestsFromTestCase(TestStringMethods)
unittest.TextTestRunner(verbosity=2).run(suite)
有时候case执行时只是入参值变化,结果都是一样
这时我们可以采用入参参数化的方式,借助parameterizd
但是uniittest框架不支持装饰器,故只有使用@parameterized.expand创建的测试才会被执行
@parameterized.expand([
('-9999', ''),
('', '-9999'),
('-8888', '-9999'),
])
def test_case_1(self, aaa, bbb):
****
代码此处省略
****
参数化的case执行:生成测试集然后运行
if __name__ == '__main__':
suite = unittest.TestSuite(Classname, "test_case_n")
runner = unittest.TextTestResult()
runner.run(suite)