如何检测Pytest类参数化中browser参数是否发生变更
Pytest检测browser参数变更实现方案
核心思路
不需要自定义全局变量存储历史browser值,依托pytest官方提供的状态存储能力和fixture作用域规则即可实现,完全符合pytest设计规范。
- 用pytest自带的
Stash机制存储上一次执行的browser标识,该存储位挂载在pytest配置对象上,生命周期和测试运行周期一致,由pytest统一管理,避免手动维护全局变量的污染问题。 - 利用class级别的自动执行fixture,在每组
browser+iteration参数对应的测试类执行周期启动时做值对比,检测到browser切换就执行机器恢复逻辑。
具体实现代码
- 先初始化Stash存储键(可以写在
conftest.py或当前测试文件头部)
import pytest from typing import Optional # 定义Stash存储键,pytest要求使用StashKey类型做索引,自带类型校验 last_browser_key = pytest.StashKey[Optional[str]]() # 测试启动时初始化存储默认值 def pytest_configure(config): config.stash[last_browser_key] = None # 保留你原有的browser fixture即可,注意将其作用域设为class,和类参数化范围匹配 @pytest.fixture(scope="class") def browser(request): # 这里替换成你原有的browser初始化逻辑 browser_ins = next(b for b in BROWSERS if b.name == request.param) yield browser_ins browser_ins.quit()
- 修改测试类代码,补全参数化scope配置和检测逻辑
@pytest.mark.parametrize('iteration', range(1, ITERATIONS + 1), scope='class') # 注意给browser参数化也加上class级scope,和上层参数化范围对齐 @pytest.mark.parametrize('browser', BROWSERS, ids=[b.name for b in BROWSERS], indirect=True, scope="class") class ClassTest: # revert_machine设为class级别autouse,同组参数只执行一次检测 @pytest.fixture(autouse=True, scope="class") def revert_machine(self, request, browser): last_browser = request.config.stash[last_browser_key] # 首次运行last_browser为None不触发恢复,后续值不一致则执行恢复 if last_browser is not None and last_browser != browser.name: # 替换成你的机器恢复逻辑 do_revert_machine() # 更新存储值为当前browser request.config.stash[last_browser_key] = browser.name yield @pytest.mark.dependency(name='test_a') def test_a(self): assert True # 注意原代码两个测试方法重名test_a,后者会覆盖前者,这里修正方法名 @pytest.mark.dependency(name='test_ams_attack_onset', depends=['test_a']) def test_ams_attack_onset(self): assert True
注意事项
- 该实现和你给出的测试用例执行顺序完全匹配:同个browser下的所有同迭代用例执行完成后,切到下一个browser前会自动触发检测和恢复。
- 所有状态存储在pytest官方提供的Stash空间中,不会污染全局命名空间,也不需要手动维护变量生命周期。
- 原代码中两个测试方法都命名为
test_a会导致后定义的方法覆盖前一个,pytest-dependency的依赖关系会失效,需要将第二个测试方法重命名为唯一名称。
内容的提问来源于stack exchange,提问作者igor
相关产品推荐
相关产品推荐

