自动化测试中ChromeDriverManager单实例复用是否合理?哪种初始化方式更优
Selenium Driver初始化方案对比与选择
针对你提出的两种driver初始化方案,结合测试隔离性、执行效率、未来并行需求三个核心维度分析如下:
方案1:每个测试独立初始化Driver(Fixture实现)
优势
- 测试隔离彻底:每个测试拥有独立的浏览器实例,完全避免上一个测试的状态(如Cookie、LocalStorage、页面缓存、操作痕迹)污染后续测试,测试结果更可靠,排查问题更简单。
- 适配未来并行需求:天然支持测试并行执行(pytest-xdist),每个进程/线程的测试都有独立driver,不会出现资源竞争或互相干扰。
- 代码逻辑简单:fixture的
yield语法清晰管理driver的创建与销毁,不易出现资源泄漏。
劣势
- 执行耗时较长:每次测试都启动/关闭浏览器,确实会增加整体执行时间。但可以通过优化缓解:
- 用
scope="module"或scope="class"替代默认的functionscope,让一个模块/测试类共用一个driver,平衡隔离性和速度。 - ChromeDriverManager会自动缓存已下载的驱动,不会每次都重新下载,首次执行后后续启动速度会提升。
- 用
方案2:全局共用一个Driver
优势
- 执行速度快:仅启动一次浏览器,省去多次启动/关闭的开销。
劣势
- 状态清理不彻底:仅执行
delete_all_cookies()不足以清除所有残留状态,还存在以下隐患:- 浏览器的
localStorage、sessionStorage不会被清除,部分网站依赖这些存储保存用户状态。 - 页面的缓存资源(如静态文件、接口缓存)可能残留,导致测试依赖旧数据。
- 上一个测试未关闭的弹窗、下拉菜单、页面跳转痕迹可能影响后续操作。
- 浏览器插件状态、全局JS变量等也可能残留。
- 浏览器的
- 代码隐藏bug:你提供的代码存在两处错误:
pytest_configure中myDriver = webdriver.Chrome(...)是局部变量,全局的myDriver仍为None,会导致后续测试报错。需改为global myDriver声明。pytest_unconfigure中的myDriver.quit缺少括号,应为myDriver.quit(),否则浏览器不会正常关闭。
- 完全不支持并行:未来如果要做测试并行,全局共用driver会导致多个测试同时操作同一个浏览器,测试结果完全不可控,重构成本极高。
最终建议
- 优先选择方案1:虽然牺牲了一点执行速度,但测试的可靠性和可维护性远高于方案2,尤其适合长期迭代的测试项目。如果觉得速度慢,调整fixture的scope为
module或class即可大幅提升效率。 - 若坚持用方案2(仅当前无并行需求时临时使用):必须完善状态清理逻辑,示例修改如下:
# conftest.py myDriver = None def pytest_configure(config): global myDriver myDriver = webdriver.Chrome(ChromeDriverManager().install()) def pytest_unconfigure(config): myDriver.quit() @pytest.fixture(autouse=True) def setup(request): request.cls.driver = myDriver # 增强状态清理 myDriver.delete_all_cookies() myDriver.execute_script('window.localStorage.clear();') myDriver.execute_script('window.sessionStorage.clear();') myDriver.get('about:blank') yield
另外,你的测试代码存在小问题:from init_tests import driver不符合pytest fixture的使用逻辑,应该直接通过self.driver调用(因为fixture已经把driver赋值给了request.cls.driver),且不建议同时混用unittest.TestCase和pytest,改成纯pytest测试类更简洁:
# some_test.py class TestSome: def test_basic(self): self.driver.get('http://localhost:4001/login') # some testing
内容的提问来源于stack exchange,提问作者dina
相关产品推荐
相关产品推荐

