运行Selenium+pytest测试遇AttributeError:conftest无driver属性求助
问题排查:AttributeError: module 'conftest' has no attribute 'driver'
错误信息
AttributeError: module 'conftest' has no attribute 'driver'
你的代码
conftest.py
import pytest from selenium import webdriver driver:webdriver.Remote @pytest.fixture def setup_teardown(): #setup global driver driver = webdriver.Chrome() driver.implicitly_wait(5) driver.maximize_window() driver.get("https://www.saucedemo.com/v1/") #run test yield #teardown driver.quit()
登录测试用例
import pytest from selenium.webdriver.common.by import By import conftest @pytest.mark.usefixture("setup_teardown") class TestCT01: def test_ct01_login_valido(self): driver = conftest.driver driver.find_element(By.ID, "user-name").send_keys("standard_user") driver.find_element(By.ID, "password").send_keys("secret_sauce") driver.find_element(By.ID, "login-button").click() assert driver.find_element(By.CLASS_NAME, "product_label").is_displayed()
错误原因
你通过全局变量driver传递浏览器实例的方式不符合pytest执行逻辑:
- 测试用例直接访问
conftest.driver时,fixturesetup_teardown里的全局变量赋值操作可能还未执行,导致模块层面的driver未被正确初始化。 - 全局变量作用域管理混乱,多测试用例并发执行时极易出现冲突。
修复方案
方案一:用pytest fixture标准方式传递driver(推荐)
这是pytest设计的标准用法,通过fixture返回实例,测试用例直接接收参数,彻底避免全局变量问题:
修改后的conftest.py:
import pytest from selenium import webdriver @pytest.fixture def driver(): # setup driver_instance = webdriver.Chrome() driver_instance.implicitly_wait(5) driver_instance.maximize_window() driver_instance.get("https://www.saucedemo.com/v1/") # 返回driver给测试用例使用 yield driver_instance # teardown driver_instance.quit()
修改后的登录测试用例:
import pytest from selenium.webdriver.common.by import By class TestCT01: def test_ct01_login_valido(self, driver): driver.find_element(By.ID, "user-name").send_keys("standard_user") driver.find_element(By.ID, "password").send_keys("secret_sauce") driver.find_element(By.ID, "login-button").click() assert driver.find_element(By.CLASS_NAME, "product_label").is_displayed()
方案二:保留全局变量(不推荐)
如果一定要用全局变量,需确保fixture执行时正确赋值模块级变量,但这种方式在多测试场景下稳定性差:
修改conftest.py:
import pytest from selenium import webdriver # 初始化driver为None driver = None @pytest.fixture def setup_teardown(): global driver driver = webdriver.Chrome() driver.implicitly_wait(5) driver.maximize_window() driver.get("https://www.saucedemo.com/v1/") yield driver.quit()
测试用例无需修改,但要确保setup_teardown fixture在测试用例执行前被正确触发(你已添加@pytest.mark.usefixture,这部分没问题)。
内容的提问来源于stack exchange,提问作者Natália
相关产品推荐
相关产品推荐

