Python unittest 模块入门指南
unittest 是 Python 标准库内置的测试框架,无需安装任何依赖。本文讲解 unittest 的编写与运行、测试设计、用例过滤、多组用例、异常断言、fixture 与 doctest。
本文依据官方文档整理,未执行运行验证或性能基准。代码片段展示局部用法,业务函数、数据和环境需按项目补齐;版本与配置以所引文档为准。
直接回答:unittest 是 Python 标准库自带的测试框架,灵感来自 JUnit,采用面向对象的写法:测试类继承 TestCase,方法即断言(assertEqual 等),并提供 setUp/tearDown 与测试套件;doctest 是另一个可与其集成的标准库模块——零安装、开箱即用。
unittest 的地位
在 pytest 大行其道的今天,unittest 依然重要:它内置在标准库里,任何 Python 环境都有;大量存量项目(包括 Python 自身)用它;理解它也是理解许多测试概念的基础。
第一个测试
被测代码 calc.py:
def divide(a, b):
if b == 0:
raise ValueError("除数不能为零")
return a / b
测试 test_calc.py:
import unittest
from calc import divide
class TestDivide(unittest.TestCase):
def test_normal(self):
self.assertEqual(divide(10, 2), 5)
def test_zero_divisor(self):
with self.assertRaises(ValueError):
divide(1, 0)
if __name__ == "__main__":
unittest.main()
运行:python -m unittest 自动发现,或 python test_calc.py 直接执行。
设计好测试
unittest 的方法命名即文档:test_正常场景 / test_除零抛异常 一目了然。常用断言:
| 方法 | 含义 |
|---|---|
assertEqual(a, b) |
相等 |
assertAlmostEqual(a, b, places=7) |
浮点近似相等 |
assertIn(x, seq) / assertIsNone(x) |
包含 / 为 None |
assertRaises(exc) |
抛异常(可作上下文管理器) |
assertEqual 的参数名是 first/second,不强制期望值在前;官方例子常用实际值在前,团队保持一致即可。
过滤与多组用例
python -m unittest test_calc.TestDivide # 指定类
python -m unittest test_calc.TestDivide.test_normal # 指定方法
python -m unittest -k zero # 按关键字(3.7+)
多组输入场景用 subTest——一处失败不影响其余组继续:
def test_various(self):
cases = [(10, 2, 5), (9, 3, 3), (1, 4, 0.25)]
for a, b, want in cases:
with self.subTest(a=a, b=b):
self.assertEqual(divide(a, b), want)
数据复杂时可以把用例抽成数据类列表循环,结构更清晰。
fixture:setUp 与 tearDown
class TestRepo(unittest.TestCase):
def setUp(self):
self.db = connect(":memory:")
def tearDown(self):
self.db.close()
@classmethod
def setUpClass(cls):
cls.config = load_test_config() # 类级一次
setUp 成功后才会执行该测试的 tearDown;若初始化中途失败,已注册的 addCleanup 仍会调用。setUp/tearDown 每条用例前后执行;setUpClass/tearDownClass 整个类一次。还能用 addCleanup 注册清理函数,比 tearDown 更细粒度。
doctest:文档即测试
def add(a, b):
"""
>>> add(1, 2)
3
>>> add(-1, 1)
0
"""
return a + b
python -m doctest calc.py -v 直接验证文档示例。它不能替代正式测试,可以发现被收集并执行的文档示例与结果不一致,不保证所有文档永远可运行——对库项目尤其有价值。
常见问题(FAQ)
Q:unittest 和 pytest 怎么选?
A:新项目推荐 pytest(更简洁、生态更强);unittest 适合零依赖场景与存量维护。好消息是 pytest 能直接运行 unittest 用例,迁移可以渐进。
Q:为什么我的测试没被发现?
A:unittest 发现规则:文件名 test*.py、类继承 TestCase、方法 test 开头,三者缺一不可。目录还需是包(有 __init__.py)或在顶层。
Q:assertEqual 和 assertTrue(a == b) 选哪个?
A:永远用专用断言。assertEqual 失败时会打印两个值的 diff;assertTrue 只会告诉你"表达式为 False",调试体验天壤之别。
官方参考
资料核对日期:2026-09-29。