Appium的使用学习

安装Appium

  1. 安装命令

    • npm install -g appium
  2. 安装完成后,在cmd中输入appium,如果看到

    [Appium] 欢迎来到 Appium vx.x.x

    说明安装成功

安装驱动

  1. 查看可安装的驱动

    cmd中输入appium driver list

    appium_driver_list.png
  1. 安装各驱动

    • 安装uiautomator2

      cmd中输入appium driver install uiautomator2

    • 安装xcuitest

      cmd中输入appium driver install xcuitest

    • 针对flutter安装

      cmd中输入appium driver install --source=npm appium-flutter-driver

      或者本地安装,

      cmd中输入appium driver install --source local /path/to/appium-flutter-driver/driver

    appium_driver_install.png

Appium Inspector

地址配置

Remote Host:127.0.0.1
Remote Port:4723

IPhone配置参数

{
  "platformName": "ios",
  "appium:automationName": "Flutter",
  "appium:bundleId": "cn.com.ShuShiKeJi.pd",
  "appium:platformVersion": "18.3.1",
  "appium:noReset": true,
  "appium:deviceName": "iPhone",
  "appium:webDriverAgentUrl": "http://localhost:8100",
  "appium:usePrebuiltWDA": false,
  "appium:useXctestrunFile": false,
  "appium:skipLogCapture": true,
  "appium:udid": "00008101-000849813698001E"
}

安卓配置参数

{
  "platformName": "Android",
  "appium:platformVersion": "15",
  "appium:deviceName": "1C021FDEE00847",
  "appium:automationName": "uiautomator2",
  "appium:appPackage": "com.reality3.realitythird",
  "appium:noReset": false,
  "appium:appActivity": "com.reality3.realitythird.global.global.MainActivity"
}

Appium-Python-Client

封装类中的驱动对象生成

from appium.options.ios.xcuitest.base import XCUITestOptions
from appium.options.android.uiautomator2.base import UiAutomator2Options
from appium import webdriver
from thirdReality import caps, logger

class uiAppiumControl:
    def __init__(self):
        """类初始化

        Args:
            deviceid (_type_): 设备序列号,IOS是UDID,Android是mac地址
        """
        self.driver: webdriver.Remote
        self.setup()

    @staticmethod
    def createIOSDriver():
        """创建IOS驱动options

        Returns:
            _type_: _description_
        """
        options = XCUITestOptions().load_capabilities(dict(caps))
        return options

    @staticmethod
    def createAndroidDriver():
        """创建安卓驱动options

        Returns:
            _type_: _description_
        """
        options = UiAutomator2Options().load_capabilities(dict(caps))
        return options

    def setup(self):
        """创建驱动对象

        Returns:
            _type_: _description_
        """
        if os_plat == "Android":
            options = uiAppiumControl.createAndroidDriver()
        elif os_plat == "IOS":
            options = uiAppiumControl.createIOSDriver()
        connect_caps = caps
        logger.debug(f"connect_caps: {connect_caps}")
        self.driver = webdriver.Remote("http://127.0.0.1:4723", options=options,keep_alive=False)
        logger.debug(f"self.driver: {self.driver}")
  • 补充:

    1. thirdReality/__init__.py中的caps定义
    if os_plat == "Android":
        caps = {
            "platformName": "Android",
            "platformVersion": androidPhone.platform_version,
            "deviceName": androidPhone.device_id,
            "automationName": "uiautomator2",
            "appPackage": androidPhone.thirdreality_package_name,
            "noReset": True,
            "appActivity": androidPhone.thirdrealtiy_activity,
        }
    
    else:
        caps = {
            "platformName": "iOS",
            "platformVersion": iosPhone.platform_version,
            "automationName": "XCUITest",
            "bundleId": iosPhone.thirdreality_package_name,
            "noReset": True,
            "webDriverAgentUrl": "http://localhost:8100",
            "usePrebuiltWDA": False,
            "useXctestrunFile": False,
            "skipLogCapture": True,
            "udid": iosPhone.device_id,
        }
    

查找元素

find_element

self.uac.driver.find_element(AppiumBy.ACCESSIBILITY_ID,"Privacy Policy")
  • AppiumBy.ACCESSIBILITY_ID是查询的方式,其他的方式包括

    IOS_PREDICATE = '-ios predicate string'
    IOS_CLASS_CHAIN = '-ios class chain'
    ANDROID_UIAUTOMATOR = '-android uiautomator'
    ANDROID_VIEWTAG = '-android viewtag'
    ANDROID_DATA_MATCHER = '-android datamatcher'
    ANDROID_VIEW_MATCHER = '-android viewmatcher'
    ACCESSIBILITY_ID = 'accessibility id'
    IMAGE = '-image'
    CUSTOM = '-custom'
    
    # For Flutter integration usage https://github.com/AppiumTestDistribution/appium-flutter-integration-driver/tree/main
    FLUTTER_INTEGRATION_SEMANTICS_LABEL = '-flutter semantics label'
    FLUTTER_INTEGRATION_TYPE = '-flutter type'
    FLUTTER_INTEGRATION_KEY = '-flutter key'
    FLUTTER_INTEGRATION_TEXT = '-flutter text'
    FLUTTER_INTEGRATION_TEXT_CONTAINING = '-flutter text containing'
    
  • "Privacy Policy"为需要查询的元素内容


xpath

模糊查询

  • contains定位方法:用以获取包含符合要求内容的元素

    uac.driver.find_element(AppiumBy.XPATH,'//*[contains(@content-desc,"Sign Up")]').click()
    
  • starts-with定位方法:用以获取开头内容符合要求的元素

    driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeButton[starts-with(@name,"Settings")]')
    

兄弟定位

由弟弟节点推出哥哥节点
  • 通过父节点获取其大哥节点

    driver.find_element_by_xpath("//div[@id='二哥节点']/../div[1]").text
    
  • preceding-sibling

    driver.find_element_by_xpath("//div[@id='二哥节点']/preceding-sibling::div[1]").text
    
由哥哥节点推出弟弟节点
  • xpath,通过父节点获取其弟弟节点

    driver.find_element_by_xpath("//div[@id='二哥节点']/../div[3]").text
    
  • following-sibling

    driver.find_element(AppiumBy.XPATH,'//*[contains(@content-desc,"Sign Up")]/following-sibling::android.widget.CheckBox').click()
    
  • Xpath轴 following

    driver.find_element_by_xpath("//div[@id='二哥节点']/following::*").text
    

父子定位

  • xpath定位: .代表当前节点; '..'代表父节点

    driver.find_element_by_xpath("//div[@id='子节点']/../..").text
    
    • <font color=red>通过find_elements从父节点获取所有指定的子节点,并通过下标操作子节点</font>

      uac.driver.find_elements(AppiumBy.XPATH, '//android.view.View[@content-desc="Sign In"]/../android.widget.EditText')[0].click()
      uac.driver.find_elements(AppiumBy.XPATH, '//android.view.View[@content-desc="Sign In"]/../android.widget.EditText')[1].click()
      
  • parent

    driver.find_element_by_xpath("//div[@id='子节点']/parent::*/parent::div").text
    

点击

通过元素点击

self.uac.driver.find_element(AppiumBy.ACCESSIBILITY_ID,"Privacy Policy").click()

通过坐标点击

指定范围点击

driver.tap([(x1, y1), (x2, y2)], duration)
  • [(x1, y1), (x2, y2)]:坐标范围
  • duration:持续时间,单位是毫秒,默认为None,可以省略

制定坐标点击

driver.tap([(x1, y1)], duration)
  • [(x1, y1)]:坐标点
  • duration:持续时间,单位是毫秒,默认为None,可以省略

问题解决

1. 'NoneType' object has no attribute 'to_capabilities'

  • 问题描述:运行代码self.dev = webdriver.Remote(connect_url,connect_caps)时,报<font color=red>AttributeError: 'NoneType' object has no attribute 'to_capabilities'</font>的错误
  • 问题分析:由于python的appium包使用是基于selenium的, 而当我们安装了最新版的selenium和最新版的appium3.0.0, 就会导致版本冲突问题
  • 解决方案:
    1. 卸载selenium和appium: pip uninstall selenium appium-python-client
    2. 安装制定的2.0版本appium:pip install appium-python-client==2.0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容