Pytest自动化测试报错:'TestTomsLogin'对象不存在'driver'属性问题排查
核心错误原因
你遇到的AttributeError主要有两个根源:
手动调用测试方法绕开了pytest的fixture机制
@pytest.mark.usefixtures("setup")是pytest的专属标记,只有当你通过pytest命令(比如pytest test_toms_login.py)运行测试时,pytest才会自动执行setupfixture,把driver和wait注入到TestTomsLogin类的实例属性中。而你手动实例化TestTomsLogin()并调用test_login(),完全跳过了这个流程,所以self.driver和self.wait根本不存在。conftest.py中的fixture存在逻辑错误
在setupfixture里,你先给request.cls.driver赋值了浏览器驱动对象,紧接着又用request.cls.driver = wait把它覆盖成了WebDriverWait对象——就算你用pytest正常运行,后续调用self.driver.find_element()时也会报错,因为WebDriverWait没有find_element方法。
分步解决方案
1. 修复conftest.py的fixture bug
把setup fixture里的覆盖代码改成给wait单独赋值:
import pytest from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from webdriver_manager.chrome import ChromeDriverManager @pytest.fixture(scope="class") def setup(request): driver = webdriver.Chrome(ChromeDriverManager().install()) driver.get("https://itera-qa.azurewebsites.net/Login") driver.maximize_window() wait = WebDriverWait(driver, 10) request.cls.driver = driver # 保留浏览器驱动的赋值 request.cls.wait = wait # 单独给wait赋值,不要覆盖driver yield driver.close()
2. 正确运行pytest测试(推荐方式)
删除手动实例化的代码:
import pytest from base.loginpage import TomsLogin @pytest.mark.usefixtures("setup") class TestTomsLogin(): def test_login(self): self.tl = TomsLogin(self.driver, self.wait) self.tl.toms_login("User1", "pwd1") # 删掉这两行手动调用的代码 # ttl = TestTomsLogin() # ttl.test_login()
然后在终端执行命令运行测试:
pytest test_toms_login.py -v
这样pytest会自动处理fixture,把driver和wait注入到测试类实例中,不会再报AttributeError。
3. 如果需要手动调试(不推荐用于正式测试)
如果你只是想手动调试代码,可以给测试类添加初始化方法,手动创建driver和wait:
import pytest from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from webdriver_manager.chrome import ChromeDriverManager from base.loginpage import TomsLogin @pytest.mark.usefixtures("setup") class TestTomsLogin(): def __init__(self): # 手动初始化driver和wait self.driver = webdriver.Chrome(ChromeDriverManager().install()) self.driver.get("https://itera-qa.azurewebsites.net/Login") self.driver.maximize_window() self.wait = WebDriverWait(self.driver, 10) def test_login(self): self.tl = TomsLogin(self.driver, self.wait) self.tl.toms_login("User1", "pwd1") self.driver.close() # 现在手动调用就不会报错了 ttl = TestTomsLogin() ttl.test_login()
但注意,这种方式完全脱离了pytest的测试框架,只适合临时调试,正式测试一定要用pytest命令运行。
内容的提问来源于stack exchange,提问作者santosh kumar

