? ? ? ?在app手工测试过程中,我们常用的操作包含有哪些呢?——滑动、输入、点击、拖动、放大缩小等,那么这些操作转化为代码,应该如何实现呢,下面简单介绍一下,方便复习。
一、swipe滑动操作
? ? ? ? 我们对页面进行滑动,但由于屏幕大小不以,无法保证都能滑动成功,所以无法直接写死一个尺寸大小,必须使用百分比坐标,去进行滑动界面操作。
1、swipe封装
# swipe函数封装
# 从右往左滑动
def swipe_left(driver,offset = 0.9):
size = driver.get_window_size() # 获取屏幕大小
height = size['height'] # 获取高度
width = size['width'] # 获取宽度
driver.swipe(start_x = width * offset,start_y = height * 0.5,
end_x = width * (1-offset),end_y = height * 0.5)
# 从左往右滑动
def swipe_right(driver,offset = 0.9):
size = driver.get_window_size()
height = size['height']
width = size['width']
driver.swipe(start_x = width * (1-offset),start_y = height * 0.5,
end_x = width * offset,end_y = height * 0.5)
# 往上滑
def swipe_up(driver,offset = 0.9):
size = driver.get_window_size()
height = size['height']
width = size['width']
driver.swipe(start_x = width * 0.5,start_y = height * offset,
end_x = width * 0.5,end_y = height * (1-offset))
# 往下滑
def swipe_down(driver,offset = 0.9):
size = driver.get_window_size()
height = size['height']
width = size['width']
driver.swipe(start_x = width * 0.5,start_y = height * (1-offset),
end_x = width * 0.5,end_y = height * offset)
if __name__ == '__main__':
from appium.webdriver import Remote
import time
caps = {'platformName': 'Android', 'deviceName': 'emulator-5554',
'appPackage': 'com.xxzb.fenwoo', 'appActivity':'com.xxzb.fenwoo.activity.addition.WelcomeActivity'}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities=caps)
driver.implicitly_wait(3) # 等待
time.sleep(5)
# 调用函数
swipe_left(driver)
2、swipe封装到Basepage
class BasePage:
def __init__(self,driver):
self.driver = driver
self.size = driver.get_window_size()
self.height = self.size['height']
self.width = self.size['width']
def swipe_left(self,offset = 0.9):
self.driver.swipe(start_x = self.width * offset, start_y = self.height * 0.5,
end_x = self.width * (1 - offset), end_y = self.height * 0.5)
# 从左往右滑动
def swipe_right(self, driver, offset=0.9):
self.driver.swipe(start_x=self.width * (1 - offset), start_y=self.height * 0.5,
end_x=self.width * offset, end_y=self.height * 0.5)
# 往上滑
def swipe_up(self,driver,offset=0.9):
self.driver.swipe(start_x=self.width * 0.5, start_y=self.height * offset,
end_x=self.width * 0.5, end_y=self.height * (1 - offset))
# 往下滑
def swipe_down(self,driver, offset=0.9):
self.driver.swipe(start_x=self.width * 0.5, start_y=self.height * (1 - offset),
end_x=self.width * 0.5, end_y=self.height * offset)
# 另外还可直接调用
def swipe(self,direct = 'left', offset = 0.9):
if direct == 'left':
return self.swipe_left(offset)
if direct == 'right':
return self.swipe_right(offset)
if direct == 'up':
return self.swipe_up(offset)
if direct == 'dowm':
return self.swipe_down(offset)
if __name__ == '__main__':
from appium.webdriver import Remote
import time
caps = {'platformName': 'Android', 'deviceName': 'emulator-5554',
'appPackage': 'com.xxzb.fenwoo', 'appActivity': 'com.xxzb.fenwoo.activity.addition.WelcomeActivity'}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities=caps)
driver.implicitly_wait(3) # 等待
time.sleep(5)
re = BasePage(driver) # 类方法调用?? ==> 注意 __init__ 拼写
re.swipe(direct='left')
time.sleep(2)
二、TouchAction & 九宫格操作
TouchAction
注意点:
1、一定要以.perform()结尾,以表执行
2、可进行链接调用
九宫格操作,屏幕解锁
思路:
action = TouchAction(driver) ==> 初始化触摸链条
action.press().wait() ==> 先按下表选中,并等待..
.move_to().wait() ==> 再移动 ,并等待。。
.move_to().wait() ==> 再移动,并等待 。。
...
.move_to().release().perform() ==> 再移动,松开并执行。
from appium.webdriver import Remote
caps = {'platformName': 'Android', 'deviceName': 'E3LBB20708105277',
'appPackage':'com.lemon.lemonban','appActivity':'com.lemon.lemonban.activity.WelcomeActivity',}
driver = Remote(command_executor = 'http://127.0.0.1:4723/wd/hub',desired_capabilities = caps)
driver.implicitly_wait(10) # 等待
def swipe_up(driver,offset = 0.9):
size = driver.get_window_size()
height = size['height']
width = size['width']
driver.swipe(start_x = width * 0.5,start_y = height * offset,
end_x = width * 0.5,end_y = height * (1-offset))
driver.back() # 返回
time.sleep(1)
driver.lock() # 锁屏
time.sleep(1)
driver.unlock() # 解开屏幕
time.sleep(2)
swipe_up(driver) # 向上滑动
el = driver.find_element(By.ID,'com.android.systemui:id/lockPatternView')
# 获取元素的坐标数据,x、y、长、宽 # {'height': 608, 'width': 608, 'x': 56, 'y': 780}
rect = el.rect
# 获取各点开始的值 开始的x轴、y轴、长、宽
start_x = rect['x']
start_y = rect['y']
width = rect['width']
height = rect['height']
point_01 = {'x':start_x + width * 1/6,'y':start_y + height * 1/6}
point_02 = {'x':start_x + width * 1/2,'y':start_y + height * 1/6}
point_03 = {'x':start_x + width * 5/6,'y':start_y + height * 1/6}
point_04 = {'x':start_x + width * 1/6,'y':start_y + height * 1/2}
point_05 = {'x':start_x + width * 1/2,'y':start_y + height * 1/2}
point_06 = {'x':start_x + width * 5/6,'y':start_y + height * 1/2}
point_07 = {'x':start_x + width * 1/6,'y':start_y + height * 5/6}
point_08 = {'x':start_x + width * 1/2,'y':start_y + height * 5/6}
point_09 = {'x':start_x + width * 5/6,'y':start_y + height * 5/6}
# 初始化动作链条,等待单位时间为:ms
# **point_01 ==> 等同于:{'x':start_x + width * 1/6,'y':start_y + height * 1/6}
action = TouchAction(driver)
action.press(**point_01).wait(200)\
.move_to(**point_04).wait(200)\
.move_to(**point_07).wait(200)\
.move_to(**point_08).wait(200)\
.move_to(**point_09).wait(200)\
.release().perform()
time.sleep(3)
三、多指操作(放大缩小)
# TouchAction ==》 单指操作
# MultiAction ==》 多指操作
基本操作思路:
a1 = TouchAction(driver) #定义第一点触屏位
a2 = TouchAction(driver) #定义第二点触屏位
a1.press().move_to().release() # 第一点移动,松开
a2.press().move_to().release() # 第二点移动,松开
MultiAction(driver).add(a1,a2).perform()
from appium.webdriver.common.multi_action import MultiAction
class BasePage:
def __init__(self,driver):
self.driver = driver
self.size = driver.get_window_size()
self.width = self.size['width']
self.height = self.size['height']
def zoom(self,offset): # 放大
action_01 = TouchAction(driver)
action_01.press(x=self.width / 2,y=self.height / 2).move_to(x=self.width / 2,y=self.height / 2 - offset).release()
action_02 = TouchAction(driver)
action_02.press(x=self.width / 2, y=self.height / 2).move_to(x=self.width / 2,y=self.height / 2 + offset).release()
m = MultiAction(self.driver)
m.add(action_01,action_02)
m.perform()
def pinch(self,offset): # 放大
action_01 = TouchAction(driver)
action_01.press(x=self.width / 2,y=self.height / 2 - offset).move_to(x=self.width / 2,y=self.height / 2).release()
action_02 = TouchAction(driver)
action_02.press(x=self.width / 2, y=self.height / 2 + offset).move_to(x=self.width / 2,y=self.height / 2).release()
m = MultiAction(self.driver)
m.add(action_01,action_02)
m.perform()
if __name__ == '__main__':
from appium.webdriver import Remote
import time
from appium.webdriver.common.touch_action import TouchAction
caps = {'platformName':'Android','deviceName':'emulator-5554','appPackage':'com.lemon.lemonban',
'appActivity':'com.lemon.lemonban.activity.WelcomeActivity',
'chromedriverExecutor':r'C:\Users\lalanala\Desktop\appium自动化资料\柠檬班_APP安装包.apk',
'automationName':'UIAutomator2'}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',desired_capabilities=caps)
driver.implicitly_wait(10)
time.sleep(2)
# 调用放大、缩小功能
# d = BasePage(driver)
# d.zoom(offset=0.9)
四、Toast弹框操作
方法一:通过text文本定位toast弹框
# actual = driver.find_element(By.XPATH,'//*[contains(@text, "{}")]'.format(text))
方法二:固定写法,判断弹框是否出现
# actual = driver.find_element(By.XPATH,'//android_widget.Toast')
from appium.webdriver import Remote
import time
from appium.webdriver.common.touch_action import TouchAction
caps = {'platformName':'Android','deviceName':'emulator-5554','appPackage':'com.lemon.lemonban',
'appActivity':'com.lemon.lemonban.activity.WelcomeActivity',
'chromedriverExecutor':r'C:\Users\lalanala\Desktop\appium自动化资料\柠檬班_APP安装包.apk',
'automationName':'UIAutomator2'}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',desired_capabilities=caps)
driver.implicitly_wait(10)
time.sleep(2)
driver.start_activity(app_package='com.lemon.lemonban',app_activity='.activity.LoginActActivity')
driver.find_element(By.ID,'com.lemon.lemonban:id/btn_login').click()
time.sleep(2)
wait = WebDriverWait(driver, 10, 0.01)
text = '手机号码或密码不能为空'
el = (MobileBy.XPATH, '//*[contains(@text, "{}")]'.format(text))
actual = wait.until(expected_conditions.presence_of_element_located(el))
assert actual
# actual = driver.find_element(By.XPATH,'//*[contains(@text, "{}")]'.format(text)) #方法一:通过text文本定位toast弹框
# actual = driver.find_element(By.XPATH,'//android_widget.Toast') # 方法二:固定写法,判断弹框是否出现
# 获取对应的toast信息,完整表示
# xpath_locator = (MobileBy.XPATH, '//*[contains(@text, "{}")]'.format('手机号码或密码不能为空'))
# try:
# WebDriverWait(driver, 10, 0.01).until(
# expected_conditions.presence_of_element_located(xpath_locator)) # 因为toast信息消失的很快,所以频率需要指定,这里设定为0.01
# print("已获取到toast信息:{}".format(driver.find_element(*xpath_locator).text))
# except:
# print("未获取到toast信息!!!")
五、快捷键操作
# 手机上的快捷键(等同于web中的键盘操作)
# 包含物理按键HOME、音量加、音量减、电源键、返回、菜单的操作
# driver.press_keycode()后接一数字,表物理按键操作,
详见:https://www.jianshu.com/p/f7ec856ff56f
from appium.webdriver import Remote
import time
driver.press_keycode(24) # 音量减
driver.press_keycode(26) # 电源键
# 其他操作
driver.lock() # 锁屏
driver.unlock() #解锁
# driver.shake() # 摇一摇
# driver.hide_keyboard() # 隐藏键盘
1、简单操作
from appium.webdriver import Remote
import time
caps={'platformName':'Android','deviceName':'emulator-5554','appPackage':'com.lemon.lemonban',
'appActivity':'com.lemon.lemonban.activity.WelcomeActivity'}
driver = Remote(command_executor = 'http://127.0.0.1:4723/wd/hub',desired_capabilities=caps)
driver.implicitly_wait(10)
time.sleep(2)
driver.press_keycode(24) # 音量减
time.sleep(3)
driver.press_keycode(26) # 电源键
time.sleep(2)
# 其他操作
driver.lock() # 锁屏
driver.unlock() #解锁
# driver.shake() # 摇一摇
# driver.hide_keyboard() # 隐藏键盘
2、两层封装
# 可实现2曾封装
class Keys:
VOLUME_UP = 24 # 音量减
VOLUME_DOWM = 25 #音量加
ENTER = 66 # 回车
POWER = 26 #电源键
class BagePage:
def __init__(self,driver):
self.driver = driver
def volue_up(self):
self.driver.press_keycode(Keys.VOLUME_UP)
def volue_dowm(self):
self.driver.press_keycode(Keys.VOLUME_DOWM)
def power(self):
self.driver.press_keycode(Keys.VOLUME_UP)
if __name__ == '__main__':
driver.implicitly_wait(10)
driver.press_keycode(Keys.POWER)
d = BagePage(driver)
d.power()
六、混合应用操作
含义 ==> 使用web技术去开发app(h5和原生app)
通过java / kotlin 开发的安卓应用程序
框架:flutter / reat native / weex
从原生app切换至web ,进行环境切换 可使用 driver.swith_to.context()
步骤:
1)按普通的安卓组件测试,
2)点击进入h5页面后,weditor、inspect 等app元素定位功能就不能使用了
3)切换环境,就变成web测试
准备:
1)辅助工具定位,uctool、chrome dectools
2)手机浏览器驱动 == 》 版本与电脑版本保持一致
3)webveiw h5必须找开发开启webview调试模式
uctool工具使用:
1)在app端进入网页,才会显示;
2)点击inspect。展示手机上的网页
3)如发现无法使用元素定位,则设置选中本地资源,
chrome devtools ==> chrome://inspect ,选中pages ==> 需翻墙
注意点:
1)caps设置驱动路径(chromedriverExecutable参数),chromedriver.exe(注意版本的兼容)
2)进入网页时,需操作网页中元素定位,需先执行:driver.swith_to.context(' ')
from appium.webdriver import Remote
caps = {'platformName': 'Android', 'deviceName': 'emulator-5554',
'appPackage':'com.lemon.lemonban','appActivity':'com.lemon.lemonban.activity.WelcomeActivity',
'chromedriverExecutable':r'C:\Users\lalanala\Desktop\appium自动化资料\chromedriver_241.exe'}
driver = Remote(command_executor = 'http://127.0.0.1:4723/wd/hub',desired_capabilities=caps)
driver.implicitly_wait(10)
print('当前环境:',driver.current_context)
print('所有环境:',driver.contexts)
driver.find_element(By.XPATH , '//*[@text="师资团队"]').click()
print('当前环境:',driver.current_context)
print('所有环境:',driver.contexts)
driver.switch_to.context('WEBVIEW_com.lemon.lemonban')
print('当前环境:',driver.current_context)
print('所有环境:',driver.contexts)
time.sleep(2)
driver.find_element(By.XPATH,"//*[text()='推荐']").click()
driver.back()
driver.switch_to.context('NATIVE_APP') # 切换环境
print('当前环境:',driver.current_context)
总结
日常小鸡汤:
该努力得努力,该学习得学习,平常心对待一切,相信一切都是自己想要的样子,fighting~!!
|