Python单元测试的基础概念
单元测试是对代码中最小可测试单元进行验证的测试方式,在Python中通常是指对单个函数、类的方法进行测试,目的是确认这些单元的逻辑符合预期。编写单元测试可以在代码修改后快速验证功能是否正常,避免引入新的问题。

为什么需要写单元测试
手动测试代码不仅效率低,还容易遗漏边界场景。单元测试可以自动化执行,每次代码变更后都能快速跑通所有用例,同时测试用例本身也是代码逻辑的补充说明,方便后续维护时理解原有功能的设计意图。
使用unittest编写单元测试
unittest是Python内置的测试框架,不需要额外安装,适合快速上手编写基础测试用例。
基础测试用例编写
首先我们定义一个需要测试的工具函数,放在math_utils.py文件中:
# math_utils.py
def add(a, b):
"""两个数相加的函数"""
return a + b
def divide(a, b):
"""两个数相除的函数,b不能为0"""
if b == 0:
raise ValueError("除数不能为0")
return a / b
接下来编写对应的测试文件test_math_utils.py,继承unittest.TestCase类:
import unittest
from math_utils import add, divide
class TestMathUtils(unittest.TestCase):
# 测试add函数的正常场景
def test_add_normal(self):
result = add(1, 2)
self.assertEqual(result, 3) # 断言结果等于3
# 测试add函数的边界场景
def test_add_negative(self):
result = add(-1, 5)
self.assertEqual(result, 4)
# 测试divide函数的正常场景
def test_divide_normal(self):
result = divide(6, 2)
self.assertEqual(result, 3)
# 测试divide函数的异常场景
def test_divide_zero(self):
# 断言调用divide(1,0)时会抛出ValueError异常
with self.assertRaises(ValueError):
divide(1, 0)
if __name__ == "__main__":
unittest.main()
运行测试文件后,如果所有用例通过会显示OK,若有失败会提示具体的错误位置和原因。
常用断言方法
unittest.TestCase提供了多种断言方法,常用的包括:
assertEqual(a, b):断言a等于bassertNotEqual(a, b):断言a不等于bassertTrue(x):断言x为TrueassertFalse(x):断言x为FalseassertRaises(异常类型, 函数, 参数):断言函数调用时会抛出指定异常
使用pytest编写单元测试
pytest是第三方测试框架,语法更简洁,功能更丰富,需要提前通过pip install pytest安装。
基础测试用例编写
同样测试上面的math_utils.py中的函数,pytest的测试文件不需要继承特定类,函数名以test_开头即可:
import pytest
from math_utils import add, divide
# 测试add函数
def test_add():
assert add(1, 2) == 3
assert add(-1, 5) == 4
assert add(0, 0) == 0
# 测试divide函数正常场景
def test_divide():
assert divide(6, 2) == 3
assert divide(5, 2) == 2.5
# 测试divide函数异常场景
def test_divide_zero():
with pytest.raises(ValueError):
divide(1, 0)
在测试文件所在目录执行pytest命令,框架会自动发现所有以test_开头的函数和文件,执行所有测试用例并输出结果。
pytest的常用特性
- 支持参数化测试,可以用
@pytest.mark.parametrize装饰器批量传入测试参数,减少重复代码 - 支持测试夹具(fixture),可以在测试用例执行前后做初始化和清理工作
- 支持测试覆盖率统计,配合pytest-cov插件可以生成覆盖率报告
单元测试的编写规范
为了保证测试用例的可读性和可维护性,编写时建议遵循以下规范:
- 测试文件命名以
test_开头,比如test_user_service.py - 测试函数命名清晰,能体现测试的场景,比如
test_user_login_with_wrong_password - 每个测试用例只验证一个逻辑点,不要在一个用例中写多个不相关的断言
- 覆盖正常场景、边界场景和异常场景,不要只测试正确输入的情况
- 测试用例之间不要有依赖,每个用例都可以独立运行
测试覆盖率统计
测试覆盖率是衡量单元测试覆盖代码程度的指标,使用pytest-cov可以统计覆盖率:
执行以下命令安装插件并运行测试统计覆盖率:
pip install pytest-cov pytest --cov=math_utils # 统计math_utils模块的覆盖率
执行后会输出每个文件的覆盖率百分比,以及未被覆盖的代码行,方便开发者补充对应的测试用例。