Python Unittest是标准库中自带的单元测试框架,无需额外安装就能使用,通过编写规范的测试用例、组织测试套件,配合自动化执行逻辑,可以实现单元测试的自动化运行,避免手动逐个执行测试的繁琐流程。

Unittest自动化测试的核心概念
要实现自动化单元测试,首先需要了解Unittest的几个核心概念:
- TestCase:测试用例的基类,所有单个测试函数都需要继承这个类来编写
- TestSuite:测试套件,用于组织多个测试用例,按照指定顺序或者规则批量执行
- TestRunner:测试运行器,负责执行测试用例,并输出测试结果
- TestLoader:测试加载器,用于自动发现指定目录下的测试用例,无需手动逐个添加
编写单个测试用例
首先我们需要有一个待测试的业务代码,比如一个简单的计算工具类:
# 待测试的计算工具类
class Calculator:
def add(self, a, b):
return a + b
def subtract(self, a, b):
return a - b
def multiply(self, a, b):
return a * b
接下来编写对应的测试用例,继承unittest.TestCase类,测试方法的名称需要以test_开头,这样Unittest才能自动识别为测试方法:
import unittest
from calculator import Calculator
class TestCalculator(unittest.TestCase):
def setUp(self):
# 每个测试方法执行前都会先执行这个方法,用于初始化测试资源
self.calc = Calculator()
def test_add(self):
# 测试加法功能
result = self.calc.add(1, 2)
self.assertEqual(result, 3)
def test_subtract(self):
# 测试减法功能
result = self.calc.subtract(5, 3)
self.assertEqual(result, 2)
def test_multiply(self):
# 测试乘法功能
result = self.calc.multiply(2, 4)
self.assertEqual(result, 8)
def tearDown(self):
# 每个测试方法执行后都会执行这个方法,用于清理测试资源
pass
自动化发现并执行测试用例
Unittest提供了TestLoader类,可以自动发现指定目录下所有符合规则的测试用例,不需要手动逐个添加测试用例到套件中,这是实现自动化的核心步骤。
假设我们的测试文件都放在tests目录下,文件命名都以test_开头,比如test_calculator.py,可以使用以下代码实现自动化执行:
import unittest
import os
if __name__ == "__main__":
# 获取当前文件所在目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 指定测试文件所在的目录,这里使用当前目录下的tests文件夹
test_dir = os.path.join(current_dir, "tests")
# 自动发现测试用例,pattern参数指定匹配的文件名规则,默认是test_*.py
suite = unittest.TestLoader().discover(test_dir, pattern="test_*.py")
# 创建测试运行器,verbosity=2表示输出详细的测试结果
runner = unittest.TextTestRunner(verbosity=2)
# 执行测试套件
runner.run(suite)
如果测试文件和运行脚本在同一个目录下,也可以直接指定当前目录为测试目录:
import unittest
if __name__ == "__main__":
# 自动发现当前目录下的所有test_开头的测试文件
suite = unittest.TestLoader().discover(".", pattern="test_*.py")
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
常用断言方法说明
在测试用例中,我们需要使用断言方法来判断测试结果是否符合预期,Unittest提供了丰富的断言方法,常用的如下:
| 断言方法 | 作用说明 |
|---|---|
| assertEqual(a, b) | 判断a和b是否相等,相等则测试通过 |
| assertNotEqual(a, b) | 判断a和b是否不相等,不相等则测试通过 |
| assertTrue(x) | 判断x是否为True,是则测试通过 |
| assertFalse(x) | 判断x是否为False,是则测试通过 |
| assertIn(a, b) | 判断a是否在b中,是则测试通过 |
| assertNotIn(a, b) | 判断a是否不在b中,是则测试通过 |
| assertRaises(Error, func, *args) | 判断执行func(*args)时是否抛出指定的Error异常,是则测试通过 |
测试固件的执行顺序
每个测试用例的执行过程中,测试固件的执行顺序如下:
- 执行测试类的
setUpClass方法(类方法,整个测试类执行前只执行一次) - 执行第一个测试方法的
setUp方法 - 执行第一个测试方法本身
- 执行第一个测试方法的
tearDown方法 - 执行第二个测试方法的
setUp方法 - 执行第二个测试方法本身
- 执行第二个测试方法的
tearDown方法 - 以此类推,直到所有测试方法执行完成
- 执行测试类的
tearDownClass方法(类方法,整个测试类执行后只执行一次)
如果需要在整个测试类执行前后做一次性初始化和清理,可以使用setUpClass和tearDownClass,注意这两个方法需要添加@classmethod装饰器:
import unittest
class TestDemo(unittest.TestCase):
@classmethod
def setUpClass(cls):
# 整个测试类执行前执行一次,比如连接数据库
print("测试类开始执行,初始化资源")
@classmethod
def tearDownClass(cls):
# 整个测试类执行后执行一次,比如关闭数据库连接
print("测试类执行结束,清理资源")
def setUp(self):
print("单个测试方法开始执行")
def test_case1(self):
self.assertEqual(1+1, 2)
def test_case2(self):
self.assertEqual(2*3, 6)
自动化测试的常见使用场景
Unittest的自动化单元测试可以应用在多个场景中:
- 本地开发时,每次修改代码后自动运行相关测试用例,快速验证修改是否影响原有功能
- 集成到CI/CD流程中,每次代码提交到仓库后自动触发测试,保证提交的代码质量
- 批量回归测试,项目上线前运行所有测试用例,验证所有功能是否正常
通过合理组织测试用例、使用自动发现机制,Unittest可以很好地满足Python项目的自动化单元测试需求,减少人工测试的工作量,提升测试的准确性和效率。