appium简单的demo元素定位

Posted IT界的测试混子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了appium简单的demo元素定位相关的知识,希望对你有一定的参考价值。

appium-录制用例

录制步骤

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

在这里插入图片描述

(2)file>New Session Window

在这里插入图片描述

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

{
“platformName”: “android”,
“deviceName”: “Huawei Mate30”,
“appPackage”: “com.xueqiu.android”,
“appActivity”: “.view.WelcomeActivityAlias”,
“noReset”: “True”
}
在这里插入图片描述

(4)录制脚本
  • 点【录制】
  • 点【选择元素】
  • 选择元素:点左边的输入框
  • 点右边的【Tap】即点击输入框操作
  • 选择元素:点坐标的输入框
  • 点右边的【Send Keys】,输入文本,即向左边的输入框输入搜索关键词
  • Recoder选择【Python】语言
  • 结束【录制】
  • 复制录制脚本
    在这里插入图片描述
    动图
    在这里插入图片描述
获取包名和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()

运行效果:
在这里插入图片描述

报错

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解锁,改为开启

在这里插入图片描述

Capability设置

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

CapabilityDescriptionValues
automationNameautomation引擎Appium (default), or UiAutomator2, Espresso, or UiAutomator1 for Android, or XCUITest or Instruments for ios, or YouiEngine for application built with You.i Engine
appapp地址/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【安卓】将键盘重置为其原始状态为falsetrue or false

元素定位

手机设置
开启开发者模式

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

在这里插入图片描述[外链图片转存失败,源站可能有防盗在这里插入!链机制,建描述]议将图片上https://传(imblog.csdnimg.c-02H0505112425224.pn2qG1g?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pfZXJkdW8=,size_16,color_FFFFFF,t_70/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pfZXJkdW8=,size_16,color_FFFFFF,t_70)]

(2)设置中,已经出现【开发者选项】
在这里插入图片描述

开启指针位置

开发者选项—>指针位置,设为开启状态。开启后,顶部会有指针移动坐标,可定位屏幕上的元素的坐标。
在这里插入图片描述

定位工具:

uiautomatorviewer.bat
在这里插入图片描述

常用定位方式

       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定位建议组合定位
    在这里插入图片描述

元素常用方法

方法释义
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()

在这里插入图片描述

特殊控件toast定位

toast

  • 简短消息提示框
  • 根据设置的显示时间后自动消失
  • 系统级别控件。归属于系统settings。不在app内。

例如下图的“验证码已发送”提示语
在这里插入图片描述

定位

通过打印页面元素,可以看到toast元素

<android.widget.Toast index="1" package="com.android.settings" class="android.widget.Toast" text="验证码已发送" checkable="false" checked="false" clickable="false" enabled="false" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,0][0,0]" displayed="true" />

但是通过class="android.widget.Toast"无法定位到,因此使用Xpath通过文本定位

driver.find_element_by_xpath('//*[@text="验证码已发送"]')

注意:Capability设置需加上automationName,才可以定位到
“automationName”:“uiautomator2”

代码
# pip install appium-python-client
from appium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from appium.webdriver.common.mobileby import MobileBy

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

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

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

    def test_toast(self):
        # 点击【我的】
        self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/tab_name' and @text='我的']").click()
        # 点击【手机号】登录
        self.driver.find_element_by_id('com.xueqiu.android:id/tv_login_phone').click()
        # 输入手机号码
        self.driver.find_element_by_id('com.xueqiu.android:id/register_phone_number').send_keys("18000000000")#任意填个手机号码
        # 点击【发送验证码】
        self.driver.find_element_by_id('com.xueqiu.android:id/register_code_text').click()
        # 等待toast元素加载
        locator = (MobileBy.XPATH,'//*[@text="验证码已发送"]')
        WebDriverWait(self.driver,30).until(expected_conditions.presence_of_element_located(locator))
        # # 打印当前页面元素树
        print(self.driver.page_source)
        # toast元素
        # <android.widget.Toast index="1" package="com.android.settings" class="android.widget.Toast" text="验证码已发送" checkable="false" checked="false" clickable="false" enabled="false" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,0][0,0]" displayed="true" />
        # 等待toast元素消失
        WebDriverWait(self.driver, 30).until_not(expected_conditions.presence_of_element_located(locator))
        # 定位"重新获取"验证码按钮,获取文案
        text = self.driver.find_element_by_id('com.xueqiu.android:id/register_code_text').text
        assert "重新获取" in text
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关于appium的简单理解

Appium:元素定位(加强版)

Appium——元素定位

appium+python自动化50-生成定位对象模板templet(jinja2)

appium+python自动化50-生成定位对象模板templet(jinja2)

Appium元素定位