PyTest fixture中add_finalizer的Teardown方法失效求助
问题分析与解决方案
你的teardown不生效核心是3个问题:
- teardown定义位置错误:它被放在
driverSetup的match分支之后,但所有分支都直接return了driver,teardown函数根本不会被定义。 - teardown逻辑错误:你在teardown里重新调用
driverSetup(browser_name),这会新建一个浏览器实例,而非关闭测试中实际使用的那个。 - finalizer注册方式错误:
request.add_finalizer(teardown(driverSetup))是直接执行了teardown函数,而非注册成测试结束后触发的回调(应该传函数对象,不是调用后的结果)。
修正后的conftest.py
直接让fixture管理driver的完整生命周期,更符合PyTest的设计逻辑:
import pytest from selenium.webdriver.chrome.service import Service as ChromeService from selenium.webdriver.firefox.service import Service as FirefoxService from selenium.webdriver.edge.service import Service as EdgeService from webdriver_manager.chrome import ChromeDriverManager from webdriver_manager.firefox import GeckoDriverManager from webdriver_manager.microsoft import EdgeChromiumDriverManager from selenium import webdriver @pytest.fixture(params=["chrome", "firefox", "edge"]) def WebDriverFixture(request): print("\nStarting browser...") browser_name = request.param driver = None match browser_name: case "chrome": options = webdriver.ChromeOptions() options.add_argument('--ignore-ssl-errors=yes') options.add_argument('--ignore-certificate-errors') options.add_experimental_option("excludeSwitches", ["enable-logging"]) driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) case "firefox": options = webdriver.FirefoxOptions() options.add_argument('--ignore-ssl-errors=yes') options.add_argument('--ignore-certificate-errors') options.set_preference("excludeSwitches", "enable-logging") options.set_preference("dom.disable_beforeunload", True) driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()), options=options) case "edge": options = webdriver.EdgeOptions() options.add_argument('--ignore-ssl-errors=yes') options.add_argument('--ignore-certificate-errors') options.accept_insecure_certs = True driver = webdriver.Edge(service=EdgeService(EdgeChromiumDriverManager().install()), options=options) driver.implicitly_wait(10) # 注册测试结束后执行的teardown def teardown(): print("\nQuitting browser...") driver.quit() request.addfinalizer(teardown) return driver
简化后的测试代码
fixture的params会自动遍历所有浏览器,无需手动用@pytest.mark.parametrize传参:
import pytest from pages.login_page import LoginPage from pages.base_page import BasePage import time def test_negative_cases(WebDriverFixture): driver = WebDriverFixture # 你的测试逻辑 # ...
如果需要指定测试的浏览器,也可以调整fixture为接收外部参数的形式:
# 修改conftest.py的fixture @pytest.fixture() def WebDriverFixture(request, browser_name): print("\nStarting browser...") driver = None # 保留原有的浏览器初始化逻辑,用browser_name替代request.param # ... driver.implicitly_wait(10) def teardown(): print("\nQuitting browser...") driver.quit() request.addfinalizer(teardown) return driver # 测试文件中指定浏览器 @pytest.mark.parametrize('browser_name', ['chrome']) def test_negative_cases(WebDriverFixture, browser_name): driver = WebDriverFixture # 测试逻辑 # ...
内容的提问来源于stack exchange,提问作者Danila Sukhoparov
相关产品推荐
相关产品推荐

