unittest单元测试框架最初受到JUnit的启发,与其他语言中的主要单元测试框架有相似的风格。它支持测试自动化,共享测试的设置和关闭代码,将测试聚合到集合中,以及测试独立于报告框架。
为了实现这一点,unittest以面向对象的方式支持一些重要的概念:
test fixture:
测试fixture表示执行一个或多个测试以及任何相关的清除操作所需的准备工作。例如,这可能涉及创建临时或代理数据库、目录或启动服务器进程。通过覆盖 TestCase的setUp()和tearDown()方法来实现。
test case:
测试用例是单独的测试单元。它检查特定输入集合的特定响应。unittest提供了一个基类TestCase,可以用来创建新的测试用例。
test suite:
测试套件是测试用例、测试套件或两者的集合。它用于聚合应该一起执行的测试。
test runner:
测试运行程序是编排测试执行并向用户提供结果的组件。运行程序可以使用图形界面、文本界面或返回一个特殊值来指示执行测试的结果。
执行脚本如下:
test_demo.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time:2021/4/7 11:25
# @Author:taozi
# 步骤1.导入unittest模块
import unittest
# 编写一个python类,继承 unittest模块中的TestCase类,这就是一个测试类
# 步骤2.定义一个继承自unittest.TestCase的测试用例类
class TestDemo(unittest.TestCase):
# 必须使用@classmethod 装饰器,所有test运行前运行一次
@classmethod
def setUpClass(cls) -> None:
print("\nsetUpClass>>>>>>>>>>>>-------setUpClass")
# 每个测试case执行前先执行setUp方法,执行完毕后执行tearDown方法。
def setUp(self) -> None:
print("\n------------setUp")
# 步骤3.定义测试用例,名字以test开头,unittest会自动将test开头的方法放入测试用例集中。
def test_upper(self):
# 一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。
print("测试用例--test_upper")
self.assertEqual('fo'.upper(), 'FOO')
def test_isupper(self):
print("测试用例--test_isupper")
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
print("测试用例--test_split")
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
# 每个测试case执行前先执行setUp方法,执行完毕后执行tearDown方法。
def tearDown(self) -> None:
print("-------------- tearDown")
# 必须使用@classmethod装饰器,所有test运行完后运行一次
@classmethod
def tearDownClass(cls) -> None:
print("tearDownClass>>>>>>>>>>>>-----tearDownClass")
class TestDemo2(unittest.TestCase):
def test_demo1(self):
print("----test_demo1")
def test_demo2(self):
print("--------test_demo2")
class TestDemo3(unittest.TestCase):
def test_demo3(self):
print("==========test_demo3")
def test_demo4(self):
print("=========test_demo4")
if __name__ == '__main__':
# 步骤4.调用unittest.main() 启动测试
# 方法一:执行所有符合规则的测试类和测试用例
unittest.main()
# 方法二:将要执行的用例加入容器中执行
# suite = unittest.TestSuite()
# suite.addTest(TestDemo("test_upper"))
# suite.addTest(TestDemo("test_isupper"))
# suite.addTest(TestDemo2("test_demo1"))
# unittest.TextTestRunner().run(suite)
# 方法三:将要执行的测试类加入容器中
# suite1 = unittest.TestLoader().loadTestsFromTestCase(TestDemo)
# suite2 = unittest.TestLoader().loadTestsFromTestCase(TestDemo2)
# suite = unittest.TestSuite([suite1, suite2])
# unittest.TextTestRunner(verbosity=2).run(suite) # verbosity=2,执行日志的详细级别,默认verbosity=1
# 方法四:匹配某个目录下所有以test开头的py文件,执行这些文件下的所有测试用例,见run
run.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time:2021/4/7 12:21
# @Author:taozi
"""
# 执行方法四:匹配某个目录下所有以test开头的py文件,执行这些文件下的所有测试用例,见run
"""
import unittest
from util.HTMLTestRunner_PY3 import HTMLTestRunner
if __name__ == '__main__':
report_title = 'wo的用例执行报告'
desc = '用于展示修改样式后的HTMLTestRunner'
report_file = './result.html'
test_dir = "./testcases" # test_dir被测试脚本的路径
discover = unittest.defaultTestLoader.discover(test_dir, pattern="test*.py") # discover可以一次调用多个脚本 pattern脚本名称匹配规则
# unittest.TextTestRunner(verbosity=2).run(discover)
with open(report_file, 'wb') as report:
runner = HTMLTestRunner(stream=report, title=report_title, description=desc)
runner.run(discover)
测试报告截图: