元素定位主要用来获取元素信息,获取元素信息后才能用appium提供的相关API去识别和操作元素。谷歌在AndroidSDK中,提供了元素定位工具uiautomatorviewer,该工具可在android-sdk安装路径下找到:
<android-sdk>\tools\bin\uiautomatorviewer.bat
博主的是在这个路径下
D:\Android\android-sdk-windows\tools
使用步骤:
1、在虚拟机或真机上打开要识别的app
2、在命令窗口输入uiautomatorviewer命令
3、然后点击DeviceScreenshot按钮连接手机
步骤一:
# 搜索到app.uix
adb shell uiautomator dump /sdcard/app.uix
# 存放在本地的路径
adb pull /sdcard/app.uix D:\Android
步骤二:
# 搜索图片
adb shell screencap -p /sdcard/app.png
# 保存图片到本地
adb pull /sdcard/app.png D:\Android\app.png
导入之后就可以识别app的页面元素了,不过用的人都比较少了,一个是软件不太行,对部分机型不兼容,一个是操作起来不太友好,所以我们下面介绍Appnium
之前其实我们已经介绍过appnium的操作原理了,接下来再来复习一下
appium支持多平台,包括MAC和Windows。它针对这两大平台开发了appium-Server
appium又同时支持Android 和 iOS两个操作系统,这就可以应用分别不同的移动设备上,覆盖市场上的大部分移动设备机型。
所以我们话不多说接着来操作
adb services
adb shell dumpsys window | findstr mCurrentFocus
mCurrentFocus=Window{c854f2d u0 com.android.calculator2/com.android.calculator2.Calculator}
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0", # 系统版本
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2", # 包名
"appActivity": "com.android.calculator2.Calculator", # 活动包名
"udid": "192.168.0.101:5555", # 设备的编号
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
运行代码之后,会自动打开我们的计算器app
首先我们进入到这个页面,然后点击这个小搜索按钮
app的定位方法跟我们之前学习的UI类似,下面将讲述一下相关的定位方式
元素的全路径,包含了全部节点。这种方法写起来很长,效率不高;另一方面由于涉及到太多层,一旦中间任何一层有变动,那元素就定位不到了
假定元素位于第8个位置,上面从第一个1位置起直到第7个位置的所有路径必须都要写,且第7个位置上有很多个元素,我们可以用下标来表示[2]
这里需要注意的是,开头为什么要用双斜杠?
其实是因为它并不是顶级目录,上面还有一个目录,不信你可以自己试试去除双斜杠,看看点击的是什么
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
# 绝对定位
driver.find_element_by_xpath(
'//android.widget.FrameLayout/android.widget.FrameLayout'
'/android.widget.FrameLayout/android.view.ViewGroup'
'/android.widget.LinearLayout/android.widget.LinearLayout[2]'
'/android.view.ViewGroup[1]/android.widget.Button[2]').click()
举例:
text属性:
driver.find_element_by_xpath(’//类名[@text=text值]’)resource-id属性: 等同于id
driver.find_element_by_xpath(’//类名[@resource-id=属性值]’)content-desc属性:
driver.find_element_by_xpath(’//类名[@content-desc=属性值]’)class属性:
driver.find_element_by_xpath(’//类名’)多属性:and表示并且or表示或者
driver.find_element_by_xpath(’//类名[@属性名=属性值and/or@属性名=属性值]’)
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
# 绝对定位
driver.find_element_by_xpath(
'//android.widget.FrameLayout/android.widget.FrameLayout'
'/android.widget.FrameLayout/android.view.ViewGroup'
'/android.widget.LinearLayout/android.widget.LinearLayout[2]'
'/android.view.ViewGroup[1]/android.widget.Button[2]').click()
# 使用text属性定位 '//属性值[@text=""]'
driver.find_element_by_xpath('//android.widget.Button[@text="+"]').click() # 点击+号
# 使用resource-id '//属性值[@resource-id=""]'
driver.find_element_by_xpath('//android.widget.Button[@resource-id="com.android.calculator2:id/digit_6"]').click() # 点击6
# 使用bounds
driver.find_element_by_xpath('//android.widget.Button[@bounds="[1184,2482][1412,2764]"]').click() # 点击=
使用部分属性内容定位:当元素的属性值过长或者元素属性值内容中存在动态变化的情况下,可以使用该方法。
起始位置匹配:
starts-with()driver.find_element_by_xpath(’//类名[starts-with(@属性名,部分属性值)]’)
包含匹配:
contains()driver.find_element_by_xpath(’//类名[contains(@属性名,部分属性值)]’)
末尾位置匹配:
ends-with()driver.find_element_by_xpath(’//类名[ends-with(@属性名,部分属性值)]’)
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
driver.find_element_by_xpath(
'//android.widget.FrameLayout/android.widget.FrameLayout'
'/android.widget.FrameLayout/android.view.ViewGroup'
'/android.widget.LinearLayout/android.widget.LinearLayout[2]'
'/android.view.ViewGroup[1]/android.widget.Button[2]').click()
# # 以什么元素开头 '//类名[contains(@元素名,"内容")]' 这里没有元素好定位的
# driver.find_element_by_xpath('//android.widget.Button[contains(@元素,"xxxxx")]').click()
# 元素包含某某内容 '//类名[contains(@元素名,"内容")]'
driver.find_element_by_xpath('//android.widget.Button[contains(@resource-id,"digit_6")]').click()
# 末尾开始匹配 '//类名[ends-with(@元素名,"内容")]'
driver.find_element_by_xpath('//android.widget.Button[ends-with(@resource-id,"eq")]').click()
appium在android端是调用其底层的UIAutomator2自动化测试框架去驱动自动化,在定位元素的时候,可以借助UIAutomator2的语法来实现定位。
在代码实现上提供的API是
find_element_by_android_uiautomator
# 方式一
find_element_by_android_uiautomator('text("值")')
# 方式二
find_element_by_android_uiautomator('newUiSelector().text("值")')
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
driver.find_element_by_android_uiautomator('text("7")').click()
driver.find_element_by_android_uiautomator('text("+")').click()
# 两种方法均可使用
driver.find_element_by_android_uiautomator('new UiSelector().text("7")').click()
driver.find_element_by_android_uiautomator('new UiSelector().text("=")').click()
# 方式一
find_element_by_android_uiautomator('resourceId("值")')
# 方式二
find_element_by_android_uiautomator('newUiSelector().resourceId("com.android.calculator2:id/eq")')
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
driver.find_element_by_android_uiautomator('resourceId("com.android.calculator2:id/digit_7")').click()
driver.find_element_by_android_uiautomator('resourceId("com.android.calculator2:id/op_add")').click()
# 两种方法均可使用
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.android.calculator2:id/digit_7")').click()
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.android.calculator2:id/eq")').click()
# 方式一
find_element_by_android_uiautomator('className("值")')
# 方式二
find_element_by_android_uiautomator('newUiSelector().className("com.android.calculator2:id/eq")')
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
driver.find_element_by_android_uiautomator('className("android.widget.ImageButton")').click()
#driver.find_element_by_android_uiautomator('newUiSelector().className("android.widget.ImageButton")').click()
driver.find_element_by_accessibility_id("contenet-desc的值").click()
driver.find_element_by_android_uiautomator('new UiSelector().description("contenet-desc的值")').click()
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
import time
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
driver.find_element_by_android_uiautomator('text("7")').click()
time.sleep(1)
driver.find_element_by_android_uiautomator('text("8")').click()
time.sleep(1)
driver.find_element_by_android_uiautomator('text("9")').click()
driver.find_element_by_accessibility_id("删除").click()
driver.find_element_by_android_uiautomator('new UiSelector().description("删除")').click()
后代元素定位使用条件:
子元素属性不定,不唯一,只能通过父元素来定位
newUiSelector().resourceId("父元素值").childSelector(className("子元素值").instance(数字))
其中childSelector可以传入resourceId、description等方法instance表示匹配的结果所有元素里面的第几个元素,从0开始计数
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
import time
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
# 点击数字9
driver.find_element_by_android_uiautomator(
'new UiSelector().resourceId("com.android.calculator2:id/pad_numeric").'
'childSelector(className("android.widget.Button").instance(2))').click()
通过子元素找到父元素,然后通过父元素再去找兄弟元素
# 是兄弟就来砍我 表示从元素的父元素下查找
driver.find_element_by_android_uiautomator('new UiSelector().text("7").fromParent(text("8"))').click()
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
import time
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator",
"udid": "192.168.0.101:5555",
"noReset": "True",
"unicodeKeyboard": "True",
"resetKeyboard": "True"
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
# # 点击数字9 父元素定位
# driver.find_element_by_android_uiautomator(
# 'new UiSelector().resourceId("com.android.calculator2:id/pad_numeric").'
# 'childSelector(className("android.widget.Button").instance(2))').click()
# 兄弟元素点击
driver.find_element_by_android_uiautomator('new UiSelector().text("7").fromParent(text("8"))').click()
H5网页是指第5代HTML,也指用H5语言制作的一切数字产品。HTML5的设计目的是为了在移动设备上支持多媒体。目前很多网站都做了自适应,通过不同端打开呈现不同的网页效果。appium支持在手机端对web网页进行UI自动化操作。
appium对手机端web网页进行自动化操作步骤如下:
1、手机端安装google浏览器apk
2、查看google浏览器apk版本,下载与之对应的appium-webdriver程序
3、把下载的appium-webdriver程序替换appium默认的webdriver程序
4、设置DesiredCapabilities时,增加’browserName’、'chromedriverExecutable’参数,去掉app启动相关参数,
注意:chrome浏览器需要安装在设备当中,虚拟器不能安装chrome.apk,推荐用真机进行测试
# -*- coding: utf-8 -*-
# @Time : 2022/1/14 10:46
# @Author : Limusen
# @File : demo_connect_01
import time
from appium import webdriver
des = {
"platformName": "Android",
"platformVersion": "9.0",
"deviceName": "Samsung Galaxy S9",
"browserName": "Chrome",
"udid": "192.168.0.101:5555",
"noReset": "True",
"chromedriverExecutable": r"D:\apk\chromedriver.exe", # 驱动地址
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des)
driver.implicitly_wait(5)
driver.get("https://www.baidu.com")
time.sleep(3)
# 语法跟ui自动化一样
driver.find_element_by_xpath("//*[@id='index-kw']").send_keys("newdream")
driver.find_element_by_id('index-bn').click()
利用谷歌浏览器开发者工具切换到手机模式后再去识别
1、在谷歌浏览器输入待测网站
2、进入菜单–更多工具–开发者工具,点击toggledevicetoolbar,切换到手机模式
3、刷新网站,此时会切换到手机版网页模式,点击开发者工具左上角选择元素按钮,再到待测网页中去点击元素识别。
1:选择元素按钮
2:toggledevicetoolbar
本章总结
本章节主要讲到的appnium如何进行元素定位,以及两个定位元素的工具
https://gitee.com/todayisgoodday/PythonAppnium
https://www.cnblogs.com/yushengaqingzhijiao/category/2024559.html