单元测试模块 unittest
unittest 的四个核心的概念:
TestLoader: 加载或分发测试任务的调度器;
TestCase: 测试用例的对象;
TestSuite: 多个测试用例的容器;
TextTestRunner: 执行测试用例的工作者;
TextTestResult: 测试结果保存的对象;
fixture: 搭建一个测试环境;
# 使用断言方法
assertEqual 如果两个值相等, 则 pass
assertNotEqual 如果两个值不相等, 则 pass
assertTrue 判断 bool 值为 True, 则 pass
assertFalse 判断 bool 值为 False, 则 pass
assertIsNone 不存在, 则 pass
assertIsNotNone 存在, 则 pass
如果断言错误, 就会报 assertionError 错误;
简单测试实例
- # mytest.py
- def add(a, b):
- return a+b
- def minus(a, b):
- return a-b
- def multi(a, b):
- return a*b
- def divide(a, b):
- return a/b
- # test.py
- import unittest
- from mytest import *
- class MathTest(unittest.TestCase):
- '''测试 main 模块'''
- def test_add(self):
- '''测试 add 函数'''
- self.assertEqual(2,add(1,1))
- def test_minus(self):
- '''测试 minus 函数'''
- self.assertEqual(2,minus(3,1))
- def test_multi(self):
- '''测试 multi 函数'''
- self.assertEqual(15,multi(3,5))
- def test_divide(self):
- '''测试 divide 函数'''
- self.assertEqual(2,divide(10,5))
- if __name__ == '__main__':
- unittest.main(verbosity=1)
执行 test.py 文件获得测试的结果.
知识点
每个继承 TestCase 的类都是一个测试用例, 其中的每一个以 test 开头的方法都是一个测试实例;
测试的实例必须以 test 开头, 否则无法被识别; 在方法下面加注释后, 在测试的结果终端可以显示;
测试的执行时没有顺序的, 完后后标志: 成功是 ., 失败是 F, 出错是 E, 跳过是 S.
unittest.main 中的 verbosity 方法可以控制报告的详细程度, 设为 0, 则不输出每一用例的执行结果; 如果设为 2, 则输出详细的执行结果, 默认为 1;
setUP() 和 tearDown()
如果需要在测试前做一些准备工作, 测试后一些扫尾的工作, 使用 setUp 和 tearDown 函数;
- import unittest
- class MathTest(unittest.TestCase):
- '''测试 main 模块'''
- def setUp(self):
- """测试前的准备工作"""
- pass
- def tearDown(self):
- """测试后的工作"""
- pass
上述两个方法会在每个 testcase 执行的前后执行, 如果想所有的测试实例只执行一次准备和结尾的工作, 使用:
- import unittest
- class MathTest(unittest.TestCase):
- '''测试 main 模块'''
- @classmethod
- def setUpClass(cls):
- """测试前的准备工作"""
- pass
- @classmethod
- def tearDownClass(cls):
- """测试后的工作"""
- pass
多个测试模块的集成
如果有多个测试文件, 每个都去手动执行的方式是不现实的, 可以使用 TestSuite.
- # test_suite.py
- import unittest
- from mytest import MathTest
- if __name__ == '__main__':
- # 创建一个 TestSuite 的容器
- suite = unittest.TestSuite()
- # 添加测试用例, 指定按照添加的顺序来
- tests = [MathTest("test_add"), MathTest("test_minus"), MathTest("test_divide")]
- # 在容器中加入
- suite.addTests(tests)
- # 可以加入单个
- # suite.addTest(MathTest("test_minus"))
- # 有时候我们并不关注执行的顺序
- tests2 = unittest.TestLoader().loadTestsFromTestCase(MathTest)
- tests1 = unittest.TestLoader().loadTestsFromTestCase(MathTest)
- # 以列表的形式加入, tests1 和 tests2 是一个容器, 容器可以嵌套容器
- suite.addTests([test1,test2])
- # 一般结果默认输出到终端, 可以设置输出到文件
- with open('UnittestTextReport.txt', 'a',encoding='utf-8') as f:
- runner = unittest.TextTestRunner(stream=f, verbosity=2)
- runner.run(suite)
跳过某些测试
在测试的 testcase 添加装饰器;
unittest.skip(reason): 无条件跳过, reason 可以用来写跳过的原因.
unittest.skipIf(condition, reason): 当 condition 为 True 是跳过; condition 可以是一个函数, 类等任何对象;
unittest.skipUnless(condition, reason): 当 condition 为 False 是跳过;
- class MathTest(unittest.TestCase):
- '''测试 main 模块'''
- @unitteat.skip('skip this add')
- def test_add(self):
- '''测试 add 函数'''
- self.assertEqual(2,add(1,1))
来源: http://www.bubuko.com/infodetail-2556265.html