appium(2)简单的demo、元素定位

appium-录制用例

录制步骤

(1)启动appium客户端,默认启动地址 http://127.0.0.1:4723/wd/hub

appium(2)简单的demo、元素定位_第1张图片

(2)file>New Session Window

appium(2)简单的demo、元素定位_第2张图片

(3)配置设备信息、包名等,点【Start Session】

{
“platformName”: “android”,
“deviceName”: “Huawei Mate30”,
“appPackage”: “com.xueqiu.android”,
“appActivity”: “.view.WelcomeActivityAlias”,
“noReset”: “True”
}
appium(2)简单的demo、元素定位_第3张图片

(4)录制脚本
  • 点【录制】
  • 点【选择元素】
  • 选择元素:点左边的输入框
  • 点右边的【Tap】即点击输入框操作
  • 选择元素:点坐标的输入框
  • 点右边的【Send Keys】,输入文本,即向左边的输入框输入搜索关键词
  • Recoder选择【Python】语言
  • 结束【录制】
  • 复制录制脚本
    appium(2)简单的demo、元素定位_第4张图片
    动图
获取包名和activity

windows系统
adb shell dumpsys activity |find “mFocusedActivity” 获取当前activity

C:\Users\Administrator>adb shell dumpsys activity |find "mFocusedActivity"
  mFocusedActivity: ActivityRecord{
     10828b7 u0 com.xueqiu.android/.common.MainActivity t11}

adb shell dumpsys window | findstr mCurrentFocus 获取当前activity

C:\Users\Administrator>adb shell dumpsys window | findstr mCurrentFocus
  mCurrentFocus=Window{
     26c290 u0 com.xueqiu.android/com.xueqiu.android.common.MainActivity}

代码


# pip install appium-python-client
from appium import webdriver
import time
descrip_cap = {
     
    "platformName": "android",
    "deviceName": "Huawei Mate30",
    "appPackage": "com.xueqiu.android",
    "appActivity": ".view.WelcomeActivityAlias",
    "noReset": "True"
}

driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",descrip_cap)
driver.implicitly_wait(10)
#####################复制录制的脚本#############################
el1 = driver.find_element_by_id("com.xueqiu.android:id/tv_search")
el1.click()
el2 = driver.find_element_by_id("com.xueqiu.android:id/search_input_text")
el2.send_keys("alibaba")
el3 = driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.LinearLayout/androidx.recyclerview.widget.RecyclerView/android.widget.RelativeLayout[1]/android.widget.LinearLayout/android.widget.TextView[1]")
el3.click()
el4 = driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.LinearLayout/androidx.viewpager.widget.ViewPager/android.widget.RelativeLayout/android.view.ViewGroup/androidx.recyclerview.widget.RecyclerView/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.FrameLayout[1]/android.widget.RelativeLayout/android.widget.LinearLayout[1]/android.widget.TextView")
el4.click()
#####################复制录制的脚本#############################
time.sleep(5)
driver.quit()

运行效果:
appium(2)简单的demo、元素定位_第5张图片

报错

An unknown server-side error occurred while processing the command. Original error: Error executing adbExec. Original error: 'Command 'D\:\\adt-bundle-windows-x86_64-20140702\\sdk\\platform-tools\\adb.exe -P 5037 -s d270ac3a shell pm clear com.xueqiu.android' exited with code 255'; Stderr: 'Security exception: PID 26038 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package com.xueqiu.android    java.lang.SecurityException: PID 26038 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package com.xueqiu.android  at com.android.server.am.ActivityManagerService.clearApplicationUserData(ActivityManagerService.java:7695)  at com.android.server.pm.PackageManagerShellCommand.runClear(PackageManagerShellCommand.java:1632)  at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:204)  at android.os.ShellCommand.exec(ShellCommand.java:103)  at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:24667)  at android.os.Binder.shellCommand(Binder.java:634)  at android.os.Binder.onTransact(Binder.java:532)  at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:3152)  at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:4970)  at android.os.Binder.execTransact(Binder.java:731)'; Code: '255'

Security exception: PID 26038 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package com.xueqiu.android
原因:
安卓手机未开启OEM解锁
解决:
设置>开发者选项>OEM解锁,改为开启

appium(2)简单的demo、元素定位_第6张图片

Capability设置

https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md

Capability Description Values
app app地址 /abs/path/to/my.apk or http://myapp.com/app.ipa
platformName 手机使用的操作系统 iOS, Android, or FirefoxOS
platformVersion 操作系统版本 e.g., 7.1, 4.4
deviceName 设备名称 iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android Emulator, Galaxy S4
udid 设备唯一标识符 e.g. 1ae203187fc012g
noReset 不重置app状态 true, false
appActivity【安卓】 启动的Android活动(页面)的活动(页面)名 MainActivity, .Settings
appPackage【安卓】 apk包名 com.example.android.myApp, com.android.settings
dontStopAppOnReset【安卓】 在adb启动应用程序之前,不会停止测试应用程序的进程 true or false
skipDeviceInitialization【安卓】 跳过设备初始化,包括.安装和运行设置应用程序或设置权限。可用于提高启动性能 true or false
unicodeKeyboard【安卓】 支持Unicode 输入, 默认为false;切换非英文输入 true or false
resetKeyboard【安卓】 将键盘重置为其原始状态为false true or false

元素定位

手机设置
开启开发者模式

(1)设置>关于手机>连续点击版本号5次以上

appium(2)简单的demo、元素定位_第7张图片appium(2)简单的demo、元素定位_第8张图片

(2)设置中,已经出现【开发者选项】
appium(2)简单的demo、元素定位_第9张图片

开启指针位置

开发者选项—>指针位置,设为开启状态。开启后,顶部会有指针移动坐标,可定位屏幕上的元素的坐标。
appium(2)简单的demo、元素定位_第10张图片

定位工具:

uiautomatorviewer.bat
appium(2)简单的demo、元素定位_第11张图片

常用定位方式

       driver.find_element_by_id(resource-id)
       driver.find_element_by_accessibility_id(content-desc)
       driver.find_element_by_xpath("//*")
  • id定位取 resource-id的值
  • accessibility_id定位取 content-desc的值
  • xpath定位建议组合定位
    appium(2)简单的demo、元素定位_第12张图片

元素常用方法

方法 释义
element.click() 点击
element.send_keys(text) 输入文本
element.se_value(value) 设置元素的值
element.clear() 清除操作
element.is_displayed() 判断元素是否可见,返回true或false
element.is_enabled() 判断元素是否可用,返回true或false
element.is_selected() 判断元素是否被选中,返回true或false
element.get_attribute(name) 获取属性值
element.text 获取元素文本
element.location 获取元素坐标.e.g.{“y”:19,“x”:20}
element.size 获取元素尺寸(高和宽)e.g.{“width”:50,“height”:42}

代码示例

# pip install appium-python-client
from appium import webdriver
import time

class TestXueQiu:
    def setup(self):
        descrip_cap = {
     
            "platformName": "android",
            "deviceName": "Huawei Mate30",
            "appPackage": "com.xueqiu.android",
            "appActivity": ".view.WelcomeActivityAlias",
            "noReset": "True",
            "unicodeKeyboard":"True",
            "resetKeyboard":"True",
        }

        self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap)
        self.driver.implicitly_wait(10)

    def teardown(self):
        time.sleep(3)
        self.driver.quit()

    def test_xueqiu(self):
        # 定位、点击搜索框
        el1 = self.driver.find_element_by_id("com.xueqiu.android:id/tv_search")
        el1.click()
        # 输入搜索关键词
        el2 = self.driver.find_element_by_id("com.xueqiu.android:id/search_input_text")
        el2.send_keys("阿里巴巴")
        #点击搜索到的词条
        el3 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']")
        el3.click()
        # 点击阿里巴巴,进入股票页面
        el4 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/stockName' and @text='阿里巴巴']")
        el4.click()
        # 获取当前股价
        el5 = self.driver.find_element_by_id("com.xueqiu.android:id/stock_current_price")
        print("阿里巴巴当前股价为:%s"% str(el5.text))
        # 判断阿里巴巴股价是否大于200
        assert float(el5.text) > 200

TouchActions

文档:
https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/touch-actions.md

常用方法:

方法 释义
press 按住
release 释放
moveTo 移动至
tap 点击
wait 等待,单位为ms
longPress 长按
perform 执行

TouchAction

TouchAction().press(el0).moveTo(el1).release()

MultiTouch同时按住多个元素

action0 = TouchAction().tap(el)
action1 = TouchAction().tap(el)
MultiAction().add(action0).add(action1).perform()

滚动

driver.execute_script("mobile: scroll", {
     "direction": "down"})
代码
# pip install appium-python-client
from appium import webdriver
import time

from appium.webdriver.common.touch_action import TouchAction


class TestTouchAction:
    def setup(self):
        descrip_cap = {
     
            "platformName": "android",
            "deviceName": "Huawei Mate30",
            "appPackage": "cn.kmob.screenfingermovelock",
            "appActivity": "com.samsung.ui.FlashActivity",
            "noReset": "True",
        }

        self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap)
        self.driver.implicitly_wait(10)

    def teardown(self):
        time.sleep(3)
        self.driver.quit()

    def test_xueqiu(self):
        #点击开启手势密码
        el1 = self.driver.find_element_by_accessibility_id("手势密码锁")
        el1.click()
        # 绘制手势密码
        # 以下坐标试用 手机分辨率为540*960
        coordinate1 = (90,128)
        coordinate2 = (272,128)
        coordinate3 = (450,128)
        coordinate4 = (272,350)
        wait_time = 220 #单位为ms毫秒
        TouchAction(self.driver).press(x=coordinate1[0],y=coordinate1[1]).wait(wait_time)\
            .move_to(x=coordinate2[0],y=coordinate2[1]).wait(wait_time)\
            .move_to(x=coordinate3[0],y=coordinate3[1]).wait(wait_time)\
            .move_to(x=coordinate4[0],y=coordinate4[1]).wait(wait_time)\
            .release().perform()
        # 点击继续
        el2 = self.driver.find_element_by_id("cn.kmob.screenfingermovelock:id/btnTwo")
        el2.click()
        # 再次绘制绘制手势密码
        TouchAction(self.driver).press(x=coordinate1[0], y=coordinate1[1]).wait(wait_time) \
            .move_to(x=coordinate2[0], y=coordinate2[1]).wait(wait_time) \
            .move_to(x=coordinate3[0], y=coordinate3[1]).wait(wait_time) \
            .move_to(x=coordinate4[0], y=coordinate4[1]).wait(wait_time) \
            .release().perform()
        # 点击确认
        el3 = self.driver.find_element_by_id("cn.kmob.screenfingermovelock:id/btnTwo")
        el3.click()

uiautomator定位

https://developer.android.com/reference/android/support/test/uiautomator/UiSelector.html

uiautomator是安卓的工作引擎,速度快,但表达式书写复杂。

常用表达式
表达式
new UiSelector().reaourceId(“id”) 通过id定位
new UiSelector().className(“className”) 通过className定位
new UiSelector().descriptioon(“content-desc”) 通过content-desc定位
new UiSelector().text(“text”) 通过文本定位
new UiSelector().textContains(“包含文本”) 通过包含文本定位
new UiSelector().textStartsWith(“以text开头”) 匹配以text开头的元素
new UiSelector().textMatches(“正则表达式”) 通过正则表达式匹配文本
childSelector() 父子关系定位
fromParent() 兄弟关系定位
组合定位:
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/name").text("阿里巴巴")')
父子关系定位:
driver.find_element_by_android_uiautomator(
            'new UiSelector().resourceId("com.xueqiu.android:id/ll_stock_result_view").childSelector(text("阿里巴巴"))')
滚动页面查找元素
 self.driver.find_element_by_android_uiautomator(
            'new UiScrollable(new UiSelector().scrollable(true).'
            'instance(0)).scrollIntoView(new UiSelector().textContains("财经").'
            'instance(0))').click()
代码
# pip install appium-python-client
from appium import webdriver
import time

class TestXueQiu:
    def setup(self):
        descrip_cap = {
     
            "platformName": "android",
            "deviceName": "Huawei Mate30",
            "appPackage": "com.xueqiu.android",
            "appActivity": ".view.WelcomeActivityAlias",
            "noReset": "True",
            "unicodeKeyboard":"True",
            "resetKeyboard":"True"
        }

        self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap)
        self.driver.implicitly_wait(10)

    def teardown(self):
        time.sleep(3)
        self.driver.quit()

    def test_check_alibaba(self):
        # 定位、点击搜索框
        # el1 = self.driver.find_element_by_id("com.xueqiu.android:id/tv_search")
        # resourceId("com.xueqiu.android:id/tv_search")
        el1 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/tv_search")')
        el1.click()
        # 输入搜索关键词
        # el2 = self.driver.find_element_by_id("com.xueqiu.android:id/search_input_text")
        el2 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/search_input_text")')
        el2.send_keys("阿里巴巴")
        #点击搜索到的词条
        # Xpath定位
        # el3 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']")
        el3 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/name").text("阿里巴巴")')
        el3.click()
        # 点击阿里巴巴,进入股票页面
        # Xpath定位
        # el4 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/stockName' and @text='阿里巴巴']")
        # el4 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/stockName").text("阿里巴巴")')
        # 通过搜索结果列表框定位其儿子节点中text为“阿里巴巴”的元素
        el4 = self.driver.find_element_by_android_uiautomator(
            'new UiSelector().resourceId("com.xueqiu.android:id/ll_stock_result_view").childSelector(text("阿里巴巴"))')
        el4.click()
        # 获取当前股价
        # el5 = self.driver.find_element_by_id("com.xueqiu.android:id/stock_current_price")
        el5 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/stock_current_price")')
        print("阿里巴巴当前股价为:%s"% str(el5.text))
        # 判断阿里巴巴股价是否大于200
        assert float(el5.text) > 200


    def test_scroll_to_article(self):
        time.sleep(1)
        # 滚动匹配包含"财经"的文本,并点击
        self.driver.find_element_by_android_uiautomator(
            'new UiScrollable(new UiSelector().scrollable(true).'
            'instance(0)).scrollIntoView(new UiSelector().textContains("财经").'
            'instance(0))').click()

踩坑

ui automator识别模拟器为横屏appium(2)简单的demo、元素定位_第13张图片

原因:
ui automator识别通过分辨率识别为横屏

解决:
设置模拟器分辨率
appium(2)简单的demo、元素定位_第14张图片

Selenium error: Could not parse UiSelector argument: ‘com.xueqiu.android:id/tv_search’ is not a stringCall to ‘10’ failed

Call to ‘10’ failed
[elements("-android uiautomator",“new UiSelector().resourceId(‘com.xueqiu.android:id/tv_search’)”)] Error response status: 9, , UnknownCommand - The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource. Selenium error: Could not parse UiSelector argument: ‘com.xueqiu.android:id/tv_search’ is not a string
appium(2)简单的demo、元素定位_第15张图片

原因:
定位表达式中使用了单引号
new UiSelector().resourceId(‘com.xueqiu.android:id/tv_search’)

解决:
定位表达式中使用了双引号
new UiSelector().resourceId(“com.xueqiu.android:id/tv_search”)
appium(2)简单的demo、元素定位_第16张图片

你可能感兴趣的:(appium,python)