4.前后置处理:setup_class/setup_method 详
承接上一篇 Pytest 入门:用例命名规则 + 命令行 + pytest.ini 配置,本篇专门解决遗留问题:Pytest 测试类禁止__init__构造方法,如何实现用例数据 / 环境初始化?
一、什么是前后置(setup/teardown)
自动化测试里的前后置:在测试用例执行之前做环境初始化、数据准备、连接数据库 / 接口登录;用例执行之后做资源释放、关闭连接、清理测试脏数据。 因为 Pytest 测试类不允许自定义__init__构造函数,框架内置两套类级别前后置方法,同时预留高级 Fixture 方案,三种实现方式:
setup_method / teardown_method:每个用例独立前后置(方法级别)setup_class / teardown_class:整个测试类只执行一次前后置(类级别)@pytest.fixture:Pytest 官方推荐灵活前后置
二、方法级前后置:setup_method & teardown_method
作用
针对类中每一条 test 开头的测试方法,执行 1 次用例就跑 1 次前置 + 后置。
适用场景:每个接口用例都需要重新登录、每次请求前重置测试数据。
完整示例代码
# test_setup_demo.py class TestExample: # 每个测试方法执行前自动执行 def setup_method(self): print("【前置】每个用例执行前:初始化数据/登录账号") # 每个测试方法执行完毕自动执行 def teardown_method(self): print("【后置】每个用例结束后:清理测试数据/关闭连接") def test_example1(self): print("=====执行测试用例1=====") def test_example2(self): print("=====执行测试用例2=====")执行命令
# -s 开启控制台print打印 pytest -vs test_setup_demo.py运行输出结果
plaintext
test_setup_demo.py::TestExample::test_example1 【前置】每个用例执行前:初始化数据/登录账号 =====执行测试用例1===== PASSED 【后置】每个用例结束后:清理测试数据/关闭连接 test_setup_demo.py::TestExample::test_example2 【前置】每个用例执行前:初始化数据/登录账号 =====执行测试用例2===== PASSED 【后置】每个用例结束后:清理测试数据/关闭连接执行逻辑总结:
用例 1:setup_method → test_example1 → teardown_method
用例 2:setup_method → test_example2 → teardown_method
三、类级前后置:setup_class & teardown_class
整个测试类只运行 1 次前置、全部用例跑完只运行 1 次后置,不随单条用例重复执行。
适用场景:一个业务模块所有接口共用一套登录 token、只需要在类开头创建一次测试账号,全部用例跑完再销毁账号。
完整示例代码
# test_setup_demo.py class TestExample: # 整个测试类执行前,仅运行1次 def setup_class(self): print("【类前置】全类只执行1次:全局登录、创建测试账号") # 整个测试类所有用例跑完后,仅运行1次 def teardown_class(self): print("【类后置】全类结束:销毁账号、关闭数据库连接") def test_example1(self): print("=====执行测试用例1=====") def test_example2(self): print("=====执行测试用例2=====")执行结果
test_setup_demo.py::TestExample::test_example1 【类前置】全类只执行1次:全局登录、创建测试账号 =====执行测试用例1===== PASSED test_setup_demo.py::TestExample::test_example2 =====执行测试用例2===== PASSED 【类后置】全类结束:销毁账号、关闭数据库连接执行逻辑总结:setup_class → test_example1 → test_example2 → teardown_class
四、组合使用:类前置 + 方法前置(企业最常用)
实际项目中经常混用两种前后置:类级别做全局初始化,方法级别做单用例私有初始化
class TestExample: # 全类一次初始化 def setup_class(self): print("【类前置】登录系统,获取全局token") # 每条用例单独初始化 def setup_method(self): print("【方法前置】单条用例:创建本次测试临时数据") def teardown_method(self): print("【方法后置】单条用例:删除临时数据") def teardown_class(self): print("【类后置】全类跑完:退出登录,释放token") def test_case1(self): print("执行用例1") def test_case2(self): print("执行用例2")五、高频踩坑:为什么不能用__init__替代 setup?
回顾上一节知识点:Pytest 测试类禁止自定义__init__(self)构造方法
- Pytest 自动收集用例时会自动实例化测试类,自定义
__init__会破坏框架实例化逻辑,导致用例收集失败、告警; __init__在类实例化时仅执行一次,无法灵活实现「每条用例都重新初始化」的需求;
✅ 正确替代:需要全类初始化用
setup_class,需要单用例初始化用setup_method。
六、两种前后置选型对照
| 方法 | 执行时机 | 执行次数 | 适用场景 |
|---|---|---|---|
| setup_method/teardown_method | 每条测试用例前后 | 用例数 = N 则执行 N 次 | 单接口独立环境、每次用例独立数据 |
| setup_class/teardown_class | 整个测试类首尾 | 一个类仅执行 1 次 | 模块接口共用登录、全局资源初始化 |
