Pytest+Appium多设备测试遇AttributeError问题求助
问题原因
根本原因是**CommonCommands类的__init__方法执行时机早于appium_driver fixture对driver属性的赋值**。Python实例化CommonCommands(或继承它的测试类)时,__init__会优先执行,而@pytest.mark.usefixtures标记的fixture要等类实例化完成后,才会把driver注入到类实例中,这时候__init__里访问self.driver自然会报属性不存在的错误。
解决方案
根据你的项目结构,提供两种可行的修复方式:
方式一:将CommonCommands设为测试类父类,延迟driver初始化
把CommonCommands作为测试类的父类,不在__init__里直接赋值self.deviceDrv,而是通过属性装饰器延迟获取driver:
1. 修改common.py
import pytest @pytest.mark.usefixtures("appium_driver") class CommonCommands: @property def deviceDrv(self): # 延迟获取driver,确保fixture已完成赋值 return self.driver # 示例通用操作方法 def click_element(self, locator): self.deviceDrv.find_element(*locator).click()
2. 修改test01.py测试类
测试类直接继承CommonCommands,父类的usefixtures标记会被继承,无需重复添加:
from common import CommonCommands class TestSample(CommonCommands): def test_click_button(self): # 直接调用父类通用方法,自动使用deviceDrv self.click_element(("id", "com.example.app:id/button"))
方式二:通过fixture传递driver初始化CommonCommands
如果不想用继承方式,可在测试类中通过fixture初始化CommonCommands并传入driver:
1. 修改common.py
移除@pytest.mark.usefixtures标记,改为初始化时接收driver参数:
class CommonCommands: def __init__(self, driver): self.deviceDrv = driver # 示例通用操作方法 def click_element(self, locator): self.deviceDrv.find_element(*locator).click()
2. 在conftest.py新增fixture初始化CommonCommands
import pytest from common import CommonCommands @pytest.fixture(scope="class") def common_commands(request): # 此时appium_driver已将driver赋值给request.cls.driver driver = request.cls.driver return CommonCommands(driver)
3. 修改test01.py测试类
同时关联appium_driver和common_commands fixture,测试方法中直接使用实例:
import pytest @pytest.mark.usefixtures("appium_driver", "common_commands") class TestSample: def test_click_button(self, common_commands): common_commands.click_element(("id", "com.example.app:id/button"))
关键注意点
- 两种方式的核心都是确保
driver被fixture赋值后再访问,避免在类__init__中过早操作未初始化的属性。 - 继承方式可减少冗余代码,父类的
usefixtures标记会被子类自动继承。
内容的提问来源于stack exchange,提问作者Archie
相关产品推荐
相关产品推荐

