unittest 案例执行顺序详解
在 unittest 框架中,测试用例的执行顺序有默认规则,也可通过自定义方式调整。以下是具体说明:
一、默认执行顺序规则
unittest 对测试用例的执行顺序遵循 “按测试方法名的 ASCII 码排序” 原则,具体逻辑如下:
- 测试类内部:所有以 test 开头的方法(如 test_login、test_register)会按方法名的字母 / 数字顺序执行。
- 多个测试类:若一个模块中有多个测试类(如 TestLogin、TestPay),类名会先按 ASCII 码排序,再执行类内部的测试方法。
示例:
import unittest class TestOrder(unittest.TestCase): def test_3(self): print("执行 test_3") def test_1(self): print("执行 test_1") def test_2(self): print("执行 test_2") if __name__ == "__main__": unittest.main() |
执行结果(按方法名排序):
执行 test_1 执行 test_2 执行 test_3 |
二、影响执行顺序的因素
- 方法名命名规范:
若方法名未遵循有序命名(如 test_a、test_b 或 test_01、test_02),可能导致执行顺序混乱。例如:
def test_login(self): ... # 可能在 test_register 之后执行(因 'l' 在 'r' 之后) def test_register(self): ... |
- 测试类加载顺序:
模块中多个测试类的执行顺序由类名的 ASCII 码决定。例如:
class TestB(unittest.TestCase): # 类名 'TestB' 会在 'TestA' 之后执行 def test_b1(self): ... class TestA(unittest.TestCase): # 先执行 def test_a1(self): ... |
- 继承或混入类:
若测试类继承了其他类,父类中的测试方法会优先于子类方法执行(同样按方法名排序)。
三、自定义执行顺序的方法
若需按业务逻辑指定执行顺序(如先登录后下单),可通过以下方式实现:
方法 1:按命名规则手动排序
通过命名规范控制顺序,推荐用 数字前缀 明确顺序:
class TestOrder(unittest.TestCase): def test_01_login(self): # 第 1 执行 print("登录") def test_02_add_cart(self): # 第 2 执行 print("加入购物车") def test_03_pay(self): # 第 3 执行 print("支付") |
方法 2:使用 unittest.TestSuite 手动添加用例
通过 TestSuite 按指定顺序逐个添加测试用例,完全掌控执行流程:
import unittest class TestShop(unittest.TestCase): def test_login(self): print("登录") def test_add_cart(self): print("加入购物车") def test_pay(self): print("支付") if __name__ == "__main__": # 创建测试套件 suite = unittest.TestSuite() # 按顺序添加测试方法(注意:方法名需用字符串传入) suite.addTest(TestShop("test_login")) suite.addTest(TestShop("test_add_cart")) suite.addTest(TestShop("test_pay")) # 执行套件 unittest.TextTestRunner().run(suite) |
执行结果(严格按添加顺序):
登录 加入购物车 支付 |
方法 3:使用第三方库(如 unittest-ordering)
通过装饰器指定顺序,需先安装库:
pip install unittest-ordering |
使用示例:
from unittest import TestCase from unittest_ordering import ordered class TestOrder(TestCase): @ordered(-1) # 数字越小越先执行 def test_login(self): print("登录") @ordered(0) def test_add_cart(self): print("加入购物车") @ordered(1) def test_pay(self): print("支付") |
四、注意事项
- 避免依赖执行顺序:
单元测试的最佳实践是 “用例独立无依赖”,即每个测试用例应能单独运行,不依赖其他用例的执行结果(例如:每个用例开始前通过 setUp() 初始化环境,结束后用 tearDown() 清理)。
- setUp() 和 tearDown() 的执行时机:
- setUp():每个测试方法执行前都会调用(如每个用例前初始化浏览器)。
- tearDown():每个测试方法执行后都会调用(如每个用例后关闭浏览器)。
它们的执行顺序不受测试方法顺序影响,只与所属方法绑定。
- 批量执行多个模块:
若通过 discover 批量加载多个模块的用例,模块文件名将先按 ASCII 码排序,再执行模块内的用例。
五、总结
- 默认顺序:按测试方法名 / 类名的 ASCII 码排序。
- 自定义顺序:通过命名规范、TestSuite 手动添加或第三方库实现。
- 最佳实践:保持用例独立性,如需依赖顺序,优先用 TestSuite 明确控制。
通过以上方式,可根据项目需求灵活控制 unittest 测试用例的执行顺序。如果需要结合具体业务场景优化执行流程,可以补充细节进一步分析~