目录结构
一、uiautomator 元素定位
1. Android UI自动化测试工具概述
2. UIAutomator定位
二、Appium元素等待的处理
1. 强制等待
2. 隐式等待
3. 显式等待
三、Toast元素识别
1. Toast简介
2. Toast 所依赖组件的安装
1)安装uiautomator2 相关组件
2)安装selenium模块
3. Toast元素识别案例:获取登录验证错误的提示语
四、部分常用操作:截屏&滑动
1. 屏幕截图
2. 滑动操作
一、uiautomator 元素定位
1. Android UI自动化测试工具概述
Android端UI自动化测试的支持工具:
- uiautomatorviewer:Android SDK自带的一个元素定位工具,用来分析UI控件的图形界面工具,位于Android SDK目录下的tools文件夹中
- uiautomator:一个测试用的Java库,包含了创建UI测试的各种API、以及执行自动化测试的引擎;Android4.3之后UIAutomator作为系统自带的UI自动化测试工具
运行原理:
电脑端运行自动化测试脚本,调用webdriver接口,appium server接收到电脑端发送过来的命令后会将这些命令转换为UIautomator可识别的命令,然后由UIautomator在移动设备上执行自动化测试
2. UIAutomator定位
UlAutomator进行元素定位,是Android系统原生支持的定位方式,支持元素全部属性的定位。其定位原理是通过Android自带的Android uiautomator的类库去查找元素。Appium元素定位的方法本质上也是基于Uiautomator进行封装来使用的
使用方法:
find_element_by_android_uiautomator()
定位方法:
id 定位
text 定位
class name 定位
1)id定位
id定位是根据元素的resource-id属性进行定位,使用 UiSelector.resourceId() 方法
如:
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("xxx")
').send_keys("yyy")
2)text定位
如:find_element_by_android_uiautomator('new UiSelector().text("xxx")
')
3)class name定位
如:find_element_by_android_uiautomator('new UiSelector().className("xxx")
')
二、Appium元素等待的处理
元素等待:灵活应对不同网络环境下加载速度的场景,增强脚本的健壮性,提高执行效率
元素等待类型:
1. 强制等待
设置固定的等待时间,使用sleep()方法
from time import sleep
sleep(5)
2. 隐式等待
针对全部元素而设置的等待时间
driver.implicitly_wait(20)
3. 显式等待
针对某个元素来设置的等待时间
from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
参数说明
driver:表示WebDriver
timeout:最长超时实践,默认以秒为单位
poll_frequency:休眠实践的间隔时间,默认0.5s
ignored_exceptions:超时后的异常信息,默认抛NoSuchElementException异常
WebDriver() 一般和until()或until_not()方法配合使用,如:
# 定位到指定id的元素,最多只会等待10s,超时则会报错
# lambda运行时动态创建函数的方法,此处设置需要等待的元素
WebDriverWait(driver,10).until(lambda x:x.find_element_by_id(yyy))
三、Toast元素识别
1. Toast简介
Android的Toast是一种简易的浮动的消息提示框,不会获得焦点,无法被点击。Toast类的思想尽可能不引人注意,同时还向用户显示信息,使其能看到。Toast显示的时间有限,一般3s左右就消失,因此使用传统的元素定位工具无法定位到元素
Toast应用场景:捕获APP使用过程中弹出的提示语元素内容,如 "用户名或密码错误"
2. Toast 所依赖组件的安装
1)安装uiautomator2 相关组件
Appium 1.6.3及以上版本,开始支持识别Toast内容,主要基于UiAutomator2,因此需要在 Capability新增配置参数:desired_caps['automationName']='uiautomator2'
capability.py
from appium import webdriver
from selenium.common.exceptions import NoSuchElementException
# 定义字典,存储capabilities配置信息
desired_caps={}
# 移动设备信息(Android模拟器)
desired_caps['platformName']='Android'
desired_caps['deviceName']='127.0.0.1:62001'
desired_caps['platformVersion']='5.1.1'
# 基于uiautomator2识别Toast
desired_caps['automationName']='uiautomator2'
# 设置键盘输入法Unicode格式
desired_caps['unicodeKeyboard']='True'
desired_caps['resetKeyboard']='True'
# 重置登录状态(每次都需要输入[用户名+密码]登录)
desired_caps['noReset']='False'
# 移动APP应用信息
desired_caps['app']=r'C:\Users\Administrator\Desktop\kaoyanbang_3.3.8beta.244.apk'
desired_caps['appPackage']='com.tal.kaoyan'
desired_caps['appActivity']='com.tal.kaoyan.ui.activity.SplashActivity'
# 连接远程服务器,根据配置开启会话
driver=webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
driver.implicitly_wait(10) # 等待时间(隐式)
# 定义点击取消升级按钮的方法
def check_cancelBtn():
print('check cancel Button')
try:
cancelBtn=driver.find_element_by_id('android:id/button2')
except NoSuchElementException:
print('no cancel button')
else:
cancelBtn.click()
# 定义点击跳过引导页的方法
def check_skipBtn():
print('check skip Button')
try:
skipBtn=driver.find_element_by_id('com.tal.kaoyan:id/tv_skip')
except NoSuchElementException:
print('no skip button')
else:
skipBtn.click()
# 调用函数
check_cancelBtn()
check_skipBtn()
安装appium-uiautomator2-driver的命令:
cnpm install appium-uiautomator2-driver


安装成功后可在 node_modules 目录(C:\Users\Administrator\node_modules)下查看到如下文件:
appium-uiautomator2-driver@1.33.1@appium-uiautomator2-driver
appium-uiautomator2-server@3.6.0@appium-uiautomator2-server

2)安装selenium模块
# 安装
pip install selenium
# 检查安装版本信息
pip show selenium

3. Toast元素识别案例:获取登录验证错误的提示语
测试场景:
用户进入登录界面,输入错误的用户名或密码,获取如下Toast内容:
① "用户名或密码登录错误,你还可以尝试4次"
② "验证失败次数过多,请15分钟后再试"
当识别到以上对应的提示信息时,则匹配打印提示内容,否则会系统报错
get_toast.py
# coding=utf-8
from capability import driver
from selenium.webdriver.support.ui import WebDriverWait
# 定位到用户名输入框;发送用户名
username=driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext')
username.clear()
username.send_keys('abc111')
# 定位到密码输入框;发送密码
password=driver.find_element_by_id('com.tal.kaoyan:id/login_password_edittext')
password.send_keys('123')
# 点击登录
driver.find_element_by_id('com.tal.kaoyan:id/login_login_btn').click()
# 定义toast提示内容
err_msg="用户名或密码错误,你还可以尝试3次"
lim_msg="验证失败次数过多,请15分钟后再试"
# 对以上提示内容进行格式化(相当于将提示内容放入@text属性的引号中)
message1='//*[@text=\'{}\']'.format(err_msg)
message2='//*[@text=\'{}\']'.format(lim_msg)
# 定位到需要等待的元素,等待15s
toast_element1=WebDriverWait(driver,15).until(lambda x:x.find_element_by_xpath(message1))
print(toast_element1.text) # 获取到元素,则打印对应属性;否则超时抛异常
# toast_element2=WebDriverWait(driver,15).until(lambda x:x.find_element_by_xpath(message2))
# print(toast_element2.text)
预先准备:
Appium版本:1.6.3及以上
adb已连接Android设备:adb connect 127.0.0.1:62001
已启动Appium Server:appium
capability.py已新增配置参数:desired_caps['automationName']='uiautomator2'
执行测试:python get_toast.py


四、部分常用操作:截屏&滑动
1. 屏幕截图
方法1:
save_screenshot()
直接保存当前屏幕截图到当前脚本所在的路径下
如:driver.save_screenshot('test.png')
方法2:
get_screenshot_as_file(self,filename)
将截图保留到指定文件路径下
如:driver.get_screenshot_as_file('./images/test.png')
2. 滑动操作
应用场景:图片滑动查看、屏幕滑动翻屏、上下滑动查看内容列表...
滑动方式:水平滑动、垂直滑动、任意方向滑动
滑动轨迹:

在Appium中模拟用户滑动操作,可使用swipe方法:
swipe(self, start_x, start_y, end_x, end_y, duration=None)
start_x:起点x坐标
start_y:起点y坐标
end_x:终点x坐标
end_y:终点y坐标
如:driver.swipe(100,200,900,200)
水平移动:(100,200) --> (900,200)
实践案例:
初次打开考研帮APP,进入登录界面之前,若不点击【跳过】按钮跳过介绍页面,则需要手动滑动2次,然后点击【立即体验】进入到登录界面
配置文件 capability.py
from appium import webdriver
from selenium.common.exceptions import NoSuchElementException
# 定义字典,存储capabilities配置信息
desired_caps={}
# 移动设备信息(Android模拟器)
desired_caps['platformName']='Android'
desired_caps['deviceName']='127.0.0.1:62001'
desired_caps['platformVersion']='5.1.1'
# 基于uiautomator2识别Toast
desired_caps['automationName']='uiautomator2'
# 设置键盘输入法Unicode格式
desired_caps['unicodeKeyboard']='True'
desired_caps['resetKeyboard']='True'
# 重置登录状态(每次都需要输入[用户名+密码]登录)
desired_caps['noReset']='False'
# 移动APP应用信息
desired_caps['app']=r'C:\Users\Administrator\Desktop\kaoyanbang_3.3.8beta.244.apk'
desired_caps['appPackage']='com.tal.kaoyan'
desired_caps['appActivity']='com.tal.kaoyan.ui.activity.SplashActivity'
# 连接远程服务器,根据配置开启会话
driver=webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
driver.implicitly_wait(10) # 等待时间(隐式)
# 定义点击取消升级按钮的方法
def check_cancelBtn():
print('check cancel Button')
try:
cancelBtn=driver.find_element_by_id('android:id/button2')
except NoSuchElementException:
print('no cancel button')
else:
cancelBtn.click()
# 定义点击跳过引导页的方法
def check_skipBtn():
print('check skip Button')
try:
skipBtn=driver.find_element_by_id('com.tal.kaoyan:id/tv_skip')
except NoSuchElementException:
print('no skip button')
else:
skipBtn.click()
# 调用函数
check_cancelBtn()
# check_skipBtn()
执行脚本 skipPage.py
from time import sleep
from capability import driver
# 获取屏幕尺寸:宽、高
def get_screen_size():
x=driver.get_window_size()['width']
y=driver.get_window_size()['height']
return x,y
# 显示屏幕尺寸
s=get_screen_size()
print(s)
# 向左滑动(纵坐标不变,横坐标减少)
def skipLeft():
s=get_screen_size()
x1=int(s[0]*0.9) # s[0]=x=屏幕宽度
x2=int(s[0]*0.1)
y1=int(s[1]*0.5) # s[1]=y=屏幕高度
driver.swipe(x1,y1,x2,y1,1000)
# 向左滑动2次
for i in range(2):
skipLeft()
sleep(0.5)
# 定位到【立即体验】并作点击(以上滑动2次之后)
driver.find_element_by_id('com.tal.kaoyan:id/activity_splash_guidfinish').click()
网友评论