引言
python小程序之UnitTest框架以及TestSuite书写方法
文章目录
- 引言
- 一、UnitTest框架
-
- [1.1 概念](#1.1 概念)
-
- [1.1.1 关键概念](#1.1.1 关键概念)
- [1.1.2 示例代码](#1.1.2 示例代码)
- [1.1.3 代码解释](#1.1.3 代码解释)
- [1.1.4 运行测试](#1.1.4 运行测试)
- [1.1.5 其他功能](#1.1.5 其他功能)
- [1.2 题目](#1.2 题目)
- [1.3 代码](#1.3 代码)
- [1.4 代码解释](#1.4 代码解释)
- 二、TestSuite书写方法
-
- [2.1 题目](#2.1 题目)
- [2.2 代码](#2.2 代码)
-
- [2.2.1 tool代码](#2.2.1 tool代码)
- [2.2.2 TestCase代码](#2.2.2 TestCase代码)
- [2.3 代码解释](#2.3 代码解释)
- 三、思考
-
- [3.1 UnitTest框架](#3.1 UnitTest框架)
- [3.2 TestSuite](#3.2 TestSuite)
一、UnitTest框架
1.1 概念
unittest 是 python 标准库中的一个测试框架,它提供了丰富的工具来编写和运行测试。unittest 框架的设计灵感来源于 Java 的 JUnit 测试框架,并且遵循了类似的测试组织方式
1.1.1 关键概念
-
测试用例 (TestCase) : 一个测试用例是包含一组相关测试的一个类。每个测试方法应该以
test开头,以便unittest能够自动识别它们 -
测试套件 (TestSuite): 一个测试套件是一个测试集合,可以包含多个测试用例或其它测试套件。这有助于将相关的测试组织在一起
-
测试加载器 (TestLoader): 用于从类中发现测试用例并加载到测试套件中
-
测试运行器 (TextTestRunner): 用于执行测试套件,并提供结果报告
-
断言 (Assertions): 断言是一些条件判断,用于验证程序的行为是否符合预期。如果断言失败,测试就会被标记为失败
-
setUp 和 tearDown: 这两个方法分别在每个测试方法之前和之后被调用,用来准备环境和清理资源
-
setUpClass 和 tearDownClass: 类级别的设置和清理方法,在所有测试开始前和结束后各执行一次
1.1.2 示例代码
python
import unittest
class TestStringMethods(unittest.TestCase):
def setUp(self):
# 在每个测试方法之前执行
self.name = "Alice"
print(f"Setting up for {self.name}")
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# 检查当分隔符不在字符串中时的行为
with self.assertRaises(TypeError):
s.split(2)
def tearDown(self):
# 在每个测试方法之后执行
print(f"Tearing down for {self.name}")
if __name__ == '__main__':
unittest.main()
1.1.3 代码解释
TestStringMethods继承自unittest.TestCasesetUp方法在每个测试方法之前运行,用来初始化一些共享的变量或状态test_upper,test_isupper,test_split是具体的测试方法。注意它们的名字都以test开头tearDown方法在每个测试方法之后运行,用来清理资源if __name__ == '__main__':确保当这个脚本直接运行时,unittest.main()将执行所有的测试
1.1.4 运行测试
可以通过命令行直接运行这个文件,或者在 IDE 中运行。unittest.main() 会查找所有的测试方法(以 test 开头的方法),然后依次执行它们,并显示测试结果:

1.1.5 其他功能
unittest 还支持更复杂的测试场景,例如参数化测试、跳过测试、预期失败等。此外,还可以结合其他工具如 coverage.py 来进行代码覆盖率分析,或者使用 nose 或 pytest 等第三方库来扩展测试功能
1.2 题目
学习UnitTest框架的书写方法
1.3 代码
python
import unittest
class Test_unittest(unittest.TestCase):
def test_first(self):
print('testcase1')
def test_second(self):
print('testcase2')
测试结果:

1.4 代码解释
-
导入
unittest模块:pythonimport unittest这行代码导入了
unittest模块,它是 python 标准库中用于编写和运行测试的框架 -
定义测试类
Test_unittest:pythonclass Test_unittest(unittest.TestCase):定义了一个名为
Test_unittest的测试类,并继承自unittest.TestCase。这是unittest框架的要求,所有的测试类都必须继承自unittest.TestCase。这个类名可以随意命名,但通常建议以Test开头,以便清晰地表明这是一个测试类 -
定义第一个测试方法
test_first:pythondef test_first(self): print('testcase1')- 定义了一个测试方法
test_first - 注意,测试方法的名字必须以
test_开头,这样unittest才能识别并运行它 - 在这个方法中,打印了一条消息
'testcase1'。这只是一个简单的示例,实际的测试方法通常会包含断言来验证代码的行为
- 定义了一个测试方法
-
定义第二个测试方法
test_second:pythondef test_second(self): print('testcase2')- 定义了另一个测试方法
test_second。 - 同样,这个方法也以
test_开头,并且在方法中打印了一条消息'testcase2'
- 定义了另一个测试方法
二、TestSuite书写方法
2.1 题目
- 在 tools 模块中定义 add 函数, 对两个数字进行求和计算
- 书写 TestCase 代码对 add() 进行测试
用例 1: 1, 2, 3
用例 2: 10, 20, 30
用例 3: 2, 3, 5
2.2 代码
2.2.1 tool代码
python
def addc(a, b):
return a+b
2.2.2 TestCase代码
python
from tools import addc
import unittest
class Testadd(unittest.TestCase):
def test_method1(self):
if addc(1,2) == 3:
print('测试通过')
else:
print('测试不通过')
def test_method2(self):
if addc(10,20) == 30:
print('测试通过')
else:
print('测试不通过')
def test_method3(self):
if addc(2,3) == 5:
print('测试通过')
else:
print('测试不通过')
输出结果:

2.3 代码解释
代码定义了一个简单的加法函数
addc,并使用unittest框架编写了几个测试方法来验证这个函数的正确性
-
定义
addc函数:pythondef addc(a, b): return a + b这个函数接受两个参数
a和b,并返回它们的和 -
导入
addc函数:pythonfrom tools import addc这行代码试图从
tools模块中导入addc函数。假设tools模块中确实定义了addc函数,并且该模块在当前目录或 python 路径中可用 -
导入
unittest模块:pythonimport unittest导入
unittest模块,这是 python 标准库中用于编写和运行测试的框架 -
定义测试类
Testadd:pythonclass Testadd(unittest.TestCase):定义一个名为
Testadd的测试类,并继承自unittest.TestCase。这是unittest框架的要求,所有的测试类都必须继承自unittest.TestCase -
定义第一个测试方法
test_method1:pythondef test_method1(self): if addc(1, 2) == 3: print('测试通过') else: print('测试不通过')- 定义了一个测试方法
test_method1。 - 使用
if语句检查addc(1, 2)是否等于 3 - 如果相等,打印
'测试通过';否则,打印'测试不通过'
- 定义了一个测试方法
-
定义第二个测试方法
test_method2:pythondef test_method2(self): if addc(10, 20) == 30: print('测试通过') else: print('测试不通过')- 定义了另一个测试方法
test_method2 - 使用
if语句检查addc(10, 20)是否等于 30 - 如果相等,打印
'测试通过';否则,打印'测试不通过'
- 定义了另一个测试方法
-
定义第三个测试方法
test_method3:pythondef test_method3(self): if addc(2, 3) == 5: print('测试通过') else: print('测试不通过')- 定义了第三个测试方法
test_method3 - 使用
if语句检查addc(2, 3)是否等于 5 - 如果相等,打印
'测试通过';否则,打印'测试不通过'
- 定义了第三个测试方法
三、思考
3.1 UnitTest框架
- 类名通常建议以
Test开头,以便清晰地表明这是一个测试类 - 测试方法通常会包含断言来验证代码的行为
3.2 TestSuite
代码能够工作,但 unittest 提供了更强大的断言机制来替代简单的 if 语句。这样可以更好地报告测试结果,并提供更多的信息
python
import unittest
from tools import addc
class TestAdd(unittest.TestCase):
def test_method1(self):
self.assertEqual(addc(1, 2), 3)
def test_method2(self):
self.assertEqual(addc(10, 20), 30)
def test_method3(self):
self.assertEqual(addc(2, 3), 5)
-
使用
self.assertEqual断言:self.assertEqual(expected, actual)是unittest中的一个断言方法,用于验证expected是否等于actual- 如果
expected不等于actual,测试将失败,并报告详细的错误信息
-
移除
print语句:unittest会自动报告测试的结果,不需要手动打印消息
-
如果某个测试失败,
unittest会报告详细的错误信息,快速定位问题,类似下图
