Unittest测试框架
一. 单元测试概述
是指对软件中的最小可测试单元进行检查和验证。至于“单元”的大小或范围,并没有一个明确的标准,“单元”可以是一个函数、方法、类、功能模块或者子系统。
二. 单元测试覆盖类型
给一条示例代码:
def demo_method(a, b, x):
if(a > 1 and b == 0):
x = x/a
if(a == 2 or x > 1):
x = x + 1
return x
1.语句覆盖
通过设计一定量的测试用例,保证被测试的方法每一行代码都会被执行一遍,运行测试用例的时候被击中的代码成为被覆盖的语句
测试用例: a = 3, b = 0, x = 4
漏洞: 如果if(a > 1 and b == 0)
变为if(a > 1 or b == 0):
,仍然是会正常执行完毕的。
行覆盖是一个比较薄弱的测试,不能完全依赖他。
2.判断覆盖
运行测试用例过程中被击中的判定语句
测试用例:
漏洞: 只针对多个条件组合的逻辑结果,忽略了每个条件取值情况
3.条件覆盖
关注具体每个条件的true和false
测试用例:
缺陷: 测试用例指数级增长
4.路径覆盖
覆盖所有可能的路径
测试用例:
三. Unittest测试框架
文档链接: unittest测试框架
unittest使用的步骤:
1.import unittest
2.继承unittest.TestCase
3.编写对应的测试函数
4.执行对应代码
示例代码 testStringMethods
import unittest
#类名不重要,但是建议使用Test开头
class TestStringMethods(unittest.TestCase):
#测试前的准备函数,每个测试函数执行之前都会首先执行一遍
def setUp(self) -> None:
print("setUp")
return super().setUp()
#测试结束的收尾函数,每个测试函数执行之后都会首先执行一遍
def tearDown(self) -> None:
print("tearDown")
return super().tearDown()
#所有测试用例执行之前,执行这个函数
@classmethod
def setUpClass(cls) -> None:
print("set up class")
#所有测试用例执行之后,执行这个函数
@classmethod
def tearDownClass(cls) -> None:
print("teardown class")
#测试函数名必须使用test_开头,self.assertEqual判断两个字符串是否相等
def test_upper(self):
print("test_upper")
self.assertEqual('foo'.upper(), 'FOO')
直接运行
unittest.main() 执行所有的unittest测试用例代码
测试套件的运行
TestSuite
可以打包测试用例并且执行
suite = unittest.TestSuite() #生成套件
suite.addTest(TestStringMethods("test_upper")) #添加类中的test_upper方法
suite.addTest(TestStringMethods("test_split")) #添加类中的test_split方法
unittest.TextTestRunner().run(suite) #执行套件
同时测试多个类的运行
suite1 = unittest.TestLoader().loadTestsFromTestCase(TestSearch1)
suite2 = unittest.TestLoader().loadTestsFromTestCase(TestSearch2)
suite = unittest.TestSuite([suite1, suite2])
unittest.TextTestRunner(verbosity=2).run(suite)
测试某个目录下面的所有文件
匹配某个目录下面所有以test开头的py文件,执行文件下面的所有的测试用例。
test_dir = "pytest"
discover = unittest.defaultTestLoader.discover(test_dir, "test*.py")
unittest.TextTestRunner(verbosity=2).run(discover)
使用HTMLTestRunner输出测试报告
将文件放入util包下:
测试代码:
import unittest
from util.HTMLTestRunner_PY3 import HTMLTestRunner #导入包
if __name__ == "__main__":
report_title = "用例执行报告"
desc = "用于展示修改样式后的HTMLTestRunner"
test_dir = "pytest" #测试文件目录名
report_file = "./result.html" #测试报告输出html文件名
#本质上discover仍然是一个testsuite
discover = unittest.defaultTestLoader.discover(test_dir, "test*.py")
with open(report_file, 'wb') as report:
runner = HTMLTestRunner(stream=report, title=report_title, description=desc)
runner.run(discover)
# unittest.TextTestRunner(verbosity=2).run(discover)