python+appium自动化测试-元素定位
Posted 蜗牛Tin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python+appium自动化测试-元素定位相关的知识,希望对你有一定的参考价值。
关于app自动化测试,元素定位工具有三个:
- appium自带的Appium Inspector工具
- android ADT原生的工具
- python版uiautomator2中的weditor
由于我常用的是前两个,所以下面只介绍前面两种元素定位工具(以下内容中均以微博为例子)
一、元素定位工具
(一).Appium Inspector
使用该工具的使用前提:
1.客户端通过adb devices的dos命令确认是否连接设备
2.当前连接的设备是否被其它应用程序占用
3.已安装appium desktop(appium的desktop下载地址:http://appium.io/)
使用步骤如下:
1.启动appium服务器,点击右上角的第一个按钮(放大镜按钮),如下图:
2.进入后页面显示如下图所示,一般情况下都选择本地服务
3.参数设置完成后点击右下角的Start Session,进入如下图所示页面
在该页面就可以进行元素定位了
(二).uiautomatorviewer—仅限Android设备使用
使用该工具的使用前提:
1.客户端通过adb devices的adb命令确认是否连接Android设备
2.当前连接的设备是否被其它应用程序占用
3.具有运行Android SDK功能的Windows
4.安装jdk1.8(由于目前不支持jdk1.8以上的版本,需要使用该工具要安装jdk1.8的版本)
5.使用Android5.0以上系统
6.确保为设备打开了开发人员模式,并打开USB调试
安装:
1.在android studio的启动页面当中,选择右下角的configure -> SDK Manager会弹出如图:选择android SDK -> SDK Tools,按图中勾选,点击ok进入安装,安装完成即可关闭android studio。记住图中Android SDK Location对应
2.在Android studio中找到SDK,找到uiautomator,存放的位置为:D:\\Android-SDK\\tools\\bin\\uiautomatorviewer.bat
使用步骤如下:
1.找到uiautomatorviewer.bat文件,双击打开
2.开启后页面显示如下图:
3.若在定位时出现下图问题,可以尝试以下几种解决方法:
- 查看手机是否开启开发者权限,打开USB调试
- 在adb命令提示符中输入adb devices查看手机是否连接到PC端,再使用adb shell是否能进入到手机(exit退出)
- 应用程序是否被占用
- 关闭uiautomatorviewer,重新打开是否能定位到
(三).两种定位工具的区别
- appium inspector需要启动appium服务器,填写Appium Desired Capabilities,略显麻烦,而uiautomatorviewer只需要连接手机
- appium inspector实时获取当前页面布局,而uiautomatorviewer方便存储,不需要实时获取
- appium inspector在操作App到下一页面时,刷新后经常会看到在转圈圈,很久都没有更新
- appium inspector中控件属性有xpath的绝对定位,而uiautomatorviewer没有xpath的绝对定位
- uiautomatorviewer获取页面布局时经常会获取不到
每种工具都有缺陷,选择最适合自己的就好啦
三、元素定位的方法
下面介绍几种元素定位方式,常见的元素定位方式是前三种
(一).ID定位
id对应控件属性列表中的:resource-id
driver.find_element_by_id("com.sina.weibo:id/tv_title_lookaround")
(二).XPATH定位
xpath对应控件属性列表中的:xpath(绝对定位只有appium inspector中才有)
# 绝对定位
driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.LinearLayout/android.widget.TextView")
# 相对定位
driver.find_element_by_xpath("//android.widget.Button[@text=\'登录\']")
(三).CLASSNAME定位
classname对应控件属性列表中的:class
注意:由于一个页面中可能会存在多个按钮的classname一致,但使用classname定位时,默认选择页面中的第一个classname,可以将所有classname相同的元素放置在一个list列表中,点击你所需要的位置的元素即可(列表中的元素从0开始)
driver.find_element_by_class_name("android.widget.TextView")
(四).accessibility定位
accessibility对应控件属性列表中的:content-desc
driver.find_element_by_accessibility_id("请输入手机号或邮箱")
(五).text定位
text对应控件属性列表中的:text
driver.find_element_by_name("登录")
(六).其它定位
元素定位除了使用find_element_by_xxx,还可以使用page_source,page_source能够查找到这个页面的所有元素,再通过if/else来查找目标元素是否存在于页面中
page_source = self.driver.page_source
if "image_cancel" in page_source:
self.driver.find_element(*locator).click()
elif "tips" in page_source:
pass
关于PO模式的元素定位方式,会在后面PO模式时再进行介绍
appium+python搭建自动化测试框架_Appium元素定位
1. id定位:
self.driver.find_element_by_id(‘com.tencent.mobileqq:id/btn_login‘).click()
2. class定位:
self.driver.find_element_by_class_name(‘android.widget.Button‘).click()
(注:一般一个页面上的class属性不唯一,元素不唯一的话定位会报错了)
3. 相对定位:
相对定位是先找到该元素的有对应属性的父元素节点,然后基于父元素进行元素定位。
代码举例:
此处只是举例什么是相对定位,一般有id直接可以定位当然不这么干,在没有id的情况下可以这么定位。。。。。。。。。。。
self.driver.find_element_by_id(‘com.tencent.mobileqq:id/name‘) self.driver.find_element_by_class_name(‘android.widget.Button‘).click()
uiautomatorviewer截屏:
4. xpath定位:
代码举例:
name = self.driver.find_element_by_xpath(‘//android.widget.EditText[@text="QQ号/手机号/邮箱"]‘).send_keys(‘********‘)
name = self.driver.find_element_by_xpath(‘//*[@class="android.widget.EditText" and @index="3"]‘).send_keys(‘********‘)
uiautomatorviewer截屏:
5. List定位:
List定位首先是使用find_elements_by_id(class_name/path)获取一组相同的class属性的的元素,然后使用数组下标来区分标记不同元素进行相关操作
代码举例:
一般从相册设置头像或是选择照片时,会用到list定位,因为每一张照片的id是相同,那就要通过下标来定位所选的照片了..............
images = self.driver.find_elements_by_id(‘id‘) images[5].click
6. Appium元素等待:
强制等待:设置固定的等待时间,使用sleep()方法即可实现
from time import sleep #强制等待5秒 sleep(5)
隐式等待:针对全部元素设置等待时间
driver.implicitly_wait(20)
显示等待:针对某个元素来设置的等待时间,方法WebDriverWait()一般和until()或until_not()方法配合使用,另外,lambda提供了一个运行时动态创建函数的方法
from selenium.webdriver.support.ui import WebDriverWait WebDriverWait(self.driver,3).until(lambda x:x.find_element_by_id(‘com.tencent.mobileqq:id/btn_login‘))
7. Toast元素识别:
下图为一般的toast提示,uiautomatorviewer工具是无法获取到这种toast的任何信息
代码实现:
注意如果内容为中文,必须注释#coding=utf-8,否则会因为编码导致文字识别失败
#适用toast弹窗
def get_toast(self):
error_message= "账号或密码错误,请重新输入"
limit_message=""
message1 =‘//*[@text=‘{}‘]‘.format(error_message)
#message2 = ‘//*[@text=‘{}‘]‘.format(limit_message)
toast_element = WebDriverWait(self.driver,5).until(lambda x:x.find_element_by_xpath(message1))
print(toast_element.text)
8. 屏幕截图:
方法一:save_screenshot()该方法直接保存当前屏幕截图到当前脚本所在的文件位置
self.driver.save_screenshot(‘login.png‘)
方法二:get_screenshot_as_file(self,filename)将截图保存在指定文件路径
self.driver.get_screenshot_as_file(‘.screenshotslogin.png‘)
9. 连续滑动操作_TouchAction:
Touch Action包含一系列操作,比如按压,长按,点击,移动,暂停,组成一套动作。
按压:press()
TouchAction(driver).press(x=0,y=308)
长按:longPress() ,比press多个按的时间参数duration,以毫秒为单位
long_press(x=0,y=308,duration=1000)
点击:tap()对一个元素或是控件执行点击操作
tap(self, element=None, x=None, y=None, count=1)
移动:move_to()将指针从上一个点一道指定的元素或点
move_to(self, element=None, x=None, y=None)
暂停:Wait(),暂停脚本的执行,单位为毫秒
wait(self, ms=0)
释放:release()结束行动,取消屏幕上的指针
release(self)
执行:perform()执行的操作发送到服务器的命令操作
perform(self)
代码举例:已设置手势密码锁为例,先进入密码锁的设置页面:
#导入模块 from appium.webdriver.common.touch_action import TouchAction for i in range(2): TouchAction(driver).press(x=243,y=381).wait(2000) .move_to(x=455,y=390).wait(1000) .move_to(x=455, y=390).wait(1000) .move_to(x=455, y=390).wait(1000) .release().perform()
10. 多点触控操作_MultiAction:
多点触控的类,可以模拟用户多点操作,主要包含add()和perform()两个方法
代码举例:以放大缩小百度地图为例
from appium import webdriver from appium.webdriver.common.touch_action import TouchAction from appium.webdriver.common.multi_action import MultiAction from time import sleep desired_caps = {} desired_caps[‘platformName‘] = ‘Android‘ desired_caps[‘platformVersion‘] = ‘5.1.1‘ desired_caps[‘deviceName‘] = ‘127.0.0.1:62001‘ desired_caps[‘app‘] = r‘C:UsersheberDownloadsaidumap.apk‘ # 被测试的App在电脑上的位置 desired_caps[‘appPackage‘] = ‘com.baidu.BaiduMap‘ desired_caps[‘appActivity‘] = ‘com.baidu.baidumaps.WelcomeScreen‘ desired_caps[‘noReset‘] = True driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub‘, desired_caps) # 启动app x = driver.get_window_size()[‘width‘] y = driver.get_window_size()[‘height‘] def pinch(): action1 = TouchAction(driver) action2 = TouchAction(driver) pinch_action = MultiAction(driver) action1.press(x=x*0.2, y=y*0.2).wait(1000).move_to(x=x*0.4, y=y*0.4).wait(1000).release() action2.press(x=x*0.8, y=y*0.8).wait(1000).move_to(x=x*0.6, y=y*0.6).wait(1000).release() pinch_action.add(action1,action2) print("start pinch....") pinch_action.perform() def zoom(): action1 = TouchAction(driver) action2 = TouchAction(driver) zoom_action = MultiAction(driver) action1.press(x=x*0.4, y=y*0.4).wait(1000).move_to(x=x*0.2, y=y*0.2).wait(1000).release() action2.press(x=x*0.6, y=y*0.6).wait(1000).move_to(x=x*0.8, y=y*0.8).wait(1000).release() zoom_action.add(action1,action2) print("start zoom....") zoom_action.perform() if __name__ == ‘__main__‘: for i in range(3): pinch() for i in range(3): zoom()
以上是关于python+appium自动化测试-元素定位的主要内容,如果未能解决你的问题,请参考以下文章
Appium+python移动自动化测试--Monitor/uiautomatorviewer工具及元素定位方法