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。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台