在Python开发中,编写单元测试可以有效验证单个函数、类或模块的功能是否符合预期,提前发现代码中的逻辑问题,减少后续集成和上线后的故障概率。Python生态中提供了多种单元测试工具,最常用的是标准库自带的unittest和第三方库pytest,两种方式各有特点,开发者可以根据项目需求选择使用。

使用unittest编写单元测试
unittest是Python内置的单元测试框架,不需要额外安装,适合对测试结构有规范要求的项目。编写unittest测试用例需要遵循固定的结构:定义继承unittest.TestCase的测试类,在类中编写以test开头的测试方法,使用框架提供的断言方法验证结果。
基础测试用例示例
假设我们有一个简单的计算模块,包含加法和减法函数,需要为这两个函数编写单元测试:
# 待测试的计算模块 calc.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# 对应的测试文件 test_calc.py
import unittest
from calc import add, subtract
class TestCalc(unittest.TestCase):
# 测试加法函数
def test_add(self):
result = add(1, 2)
# 断言结果等于3
self.assertEqual(result, 3)
# 测试负数相加的场景
self.assertEqual(add(-1, 1), 0)
# 测试浮点数相加的场景
self.assertEqual(add(1.5, 2.5), 4.0)
# 测试减法函数
def test_subtract(self):
result = subtract(5, 3)
self.assertEqual(result, 2)
self.assertEqual(subtract(0, 5), -5)
self.assertEqual(subtract(2.5, 1.5), 1.0)
if __name__ == '__main__':
unittest.main()
常用断言方法
unittest.TestCase提供了多种断言方法,满足不同的验证需求,常用的包括:
assertEqual(a, b):验证a和b相等assertNotEqual(a, b):验证a和b不相等assertTrue(x):验证x为TrueassertFalse(x):验证x为FalseassertIn(a, b):验证a在b中assertRaises(异常类型, 函数, 参数):验证函数调用时抛出指定异常
测试前置和后置方法
如果多个测试方法需要相同的初始化或清理操作,可以使用setUp和tearDown方法:
import unittest
class TestDemo(unittest.TestCase):
# 每个测试方法执行前都会调用
def setUp(self):
self.test_data = [1, 2, 3]
print("初始化测试数据")
# 每个测试方法执行后都会调用
def tearDown(self):
self.test_data = None
print("清理测试数据")
def test_data_length(self):
self.assertEqual(len(self.test_data), 3)
def test_data_content(self):
self.assertIn(2, self.test_data)
if __name__ == '__main__':
unittest.main()
使用pytest编写单元测试
pytest是第三方单元测试库,语法更简洁灵活,支持自动发现测试用例,不需要强制定义测试类,适合快速编写测试的场景。使用前需要先通过pip install pytest命令安装。
基础测试用例示例
同样测试上面的add和subtract函数,pytest的测试代码可以更简单:
# 测试文件 test_calc_pytest.py
from calc import add, subtract
# 直接定义测试函数,不需要继承类
def test_add():
assert add(1, 2) == 3
assert add(-1, 1) == 0
assert add(1.5, 2.5) == 4.0
def test_subtract():
assert subtract(5, 3) == 2
assert subtract(0, 5) == -5
assert subtract(2.5, 1.5) == 1.0
# 测试异常抛出
def test_add_exception():
with pytest.raises(TypeError):
add("1", 2)
注意如果测试异常场景,需要先导入pytest模块。pytest使用Python原生的assert语句进行断言,不需要记忆框架特定的断言方法,学习成本更低。
运行测试的方法
在命令行中进入测试文件所在目录,直接执行pytest命令,框架会自动发现当前目录下所有以test_开头或_test结尾的文件,以及文件中以test开头的函数或方法,执行所有测试用例并输出结果。
测试用例设计注意事项
编写单元测试时,合理的用例设计才能充分发挥测试的作用:
- 覆盖正常场景:验证功能在正常输入下的输出是否符合预期
- 覆盖边界场景:比如输入为空、输入为最大值最小值、输入类型不符合要求等情况
- 覆盖异常场景:验证代码在异常输入时是否能正确抛出异常,而不是崩溃
- 单个测试用例只验证一个功能点,避免一个用例验证多个逻辑,方便定位问题
- 测试用例之间不要有依赖关系,每个用例都可以独立运行
测试套件与持续集成
当项目中的测试用例变多时,可以通过测试套件组织测试用例,批量运行指定模块或目录的测试。unittest可以通过TestLoader加载测试用例,pytest可以通过配置文件指定测试范围。同时可以将单元测试集成到CI/CD流程中,每次代码提交后自动运行测试,保障代码质量。