pytest-bdd splinter多场景执行报错WinError 10061问题排查
问题原因
你当前的代码中,browser是全局变量,仅在conftest.py模块加载时初始化一次。第一个场景结束后调用browser.quit()会彻底关闭浏览器会话和ChromeDriver进程,此时这个全局browser对象已经失效。后续场景的pytest_bdd_before_scenario钩子尝试复用这个已失效的对象调用browser.visit(),自然会出现连接被拒绝的错误——因为对应的ChromeDriver会话已经不存在了。
解决方案
改用pytest的function级别的fixture来管理浏览器的生命周期,fixture会自动在每个场景(对应一个测试函数)执行前创建全新的浏览器实例,场景结束后销毁实例,完美匹配你“每个场景从Chrome未打开状态开始”的需求。
修改后的conftest.py代码如下:
"""conftest""" import pytest from splinter import Browser, Config APP_URL = "https://webapp_url" @pytest.fixture(scope="function", autouse=True) def browser(): """自动为每个场景创建/销毁浏览器实例""" # 前置操作:初始化浏览器并导航到目标URL browser_config = Config(fullscreen=True) driver = Browser('chrome', config=browser_config) driver.visit(APP_URL) print(f"已启动浏览器并导航至: {APP_URL}") # 将浏览器实例传递给测试场景使用 yield driver # 后置操作:场景结束后关闭浏览器 driver.quit() print("已关闭浏览器")
代码说明
scope="function":指定fixture的作用域为每个测试函数(每个pytest-bdd场景对应一个测试函数),确保每个场景都有独立的浏览器实例。autouse=True:让fixture自动应用到所有场景,无需在步骤定义中显式注入。yield关键字:分割前置和后置逻辑,yield之前的代码在场景执行前运行,之后的代码在场景执行后运行。
可选:保留场景日志的写法
如果需要保留场景前后的打印日志,可以结合fixture和pytest-bdd钩子,注意此时不需要在钩子中手动quit浏览器(fixture会自动处理):
"""conftest""" import pytest from splinter import Browser, Config APP_URL = "https://webapp_url" @pytest.fixture(scope="function") def browser(): """管理浏览器生命周期的fixture""" browser_config = Config(fullscreen=True) driver = Browser('chrome', config=browser_config) yield driver driver.quit() @pytest.hookimpl def pytest_bdd_before_scenario(scenario, browser): """场景前置操作""" print(f"Before scenario: {scenario.name}") browser.visit(APP_URL) @pytest.hookimpl def pytest_bdd_after_scenario(scenario): """场景后置操作""" print(f"After scenario: {scenario.name}")
这样既保留了场景日志,又通过fixture确保每个场景使用全新的浏览器实例,彻底解决连接被拒绝的问题。
内容的提问来源于stack exchange,提问作者On3Pl4te
相关产品推荐
相关产品推荐

