在的自动化测试过程中不可能只测试一个固定的有限界面,有的时候会遇到一些比较长的页面,这个时候就会用到滑动的操作,在 appium 中模拟用户滑动的操作需要使用 Swipe 方法,Swipe 的方法是如何定义的呢:
def swipe(self, start_x, start_y, end_x, end_y, duration=None):
/*
Swipe from one point to another point, for an optional duration.
:Args:
- start_x - x-coordinate at which to start
- start_y - y-coordinate at which to start
- end_x - x-coordinate at which to stop
- end_y - y-coordinate at which to stop
- duration - (optional) time to take the swipe, in ms.
:Usage:
driver.swipe(100, 100, 100, 400)
*/
滑动的轨迹图有:
from capability import driver
import time
# 先获取屏幕的尺寸
def get_screen_size():
x = driver.get_window_size()['width']
y = driver.get_window_size()['height']
# 直接返回一个元组
return x,y
# 向左滑动
def swipe_left():
left = get_screen_size()
x1 = int(left[0] * 0.9)
y1 = int(left[1] * 0.6)
x2 = int(left[0] * 0.2)
driver.swipe(x1, y1, x2, y1, 3000)
# 向右滑动
def swipe_right():
right = get_screen_size()
x1 = int(right[0] * 0.2)
y1 = int(right[1] * 0.6)
x2 = int(right[0] * 0.9)
driver.swipe(x1, y1, x2, y1, 3000)
# 向上滑动
def swipe_up():
up = get_screen_size()
x1 = int(up[0] * 0.5)
y1 = int(up[1] * 0.9)
y2 = int(up[0] * 0.3)
driver.swipe(x1, y1, x1, y2, 3000)
# 向下滑动
def swipe_down():
down = get_screen_size()
x1 = int(down[0] * 0.5)
y1 = int(down[0] * 0.3)
y2 = int(down[1] * 0.9)
driver.swipe(x1, y1, x1, y2, 3000)
for i in range(2):
# 可根据需要添加停留的时间
swipe_up()
swipe_down()
swipe_left()
swipe_right()
swipe 的滑动操作一般是在两个点之间的滑动,但是呢,在实际的自动化测试过程中可能会遇到一些多点连续滑动操作,比如常用的九宫格解锁、游戏中在屏幕上控制方向的方向标、连续拖动图片等
按压 | 释放 | 执行 | 长按 |
点击 | 移动 | 暂停 |
要完成这一系列的动作,需要导入appium中的 Touch Action 模块:
from capability import driver
from appium.webdriver.common.touch_action import TouchAction
按压使用的方法是: press(),开始按压一个元素或者坐标点(x,y),可以通过手指按压手机屏幕的某个位置,而 press 可以接收到按压屏幕的坐标点(x,y)
释放: .release() :结束当前的操作,释放屏幕上的指针
执行: .perform() :将执行的操作发送到服务器的命令操作
# 按压方法
def press(self, el=None, x=None, y=None):
"""
Begin a chain with a press down action at a particular element or point
"""
self._add_action('press', self._get_opts(el, x, y))
return self
# 释放方法
def release(self):
"""
End the action by lifting the pointer off the screen
"""
self._add_action('release', {})
return self
# 执行方法
def perform(self):
"""
Perform the action by sending the commands to the server to be operated upon
"""
params = {'actions': self._actions}
self._driver.execute(Command.TOUCH_ACTION, params)
# get rid of actions so the object can be reused
self._actions = []
return self
例:
TouchAction(driver).press(x=0, y=400).release().perform()
长按使用的方法: long_press() ,同样也是开始按压一个元素或者坐标点(x,y),但是 long_press() 方法中需要多传入一个时间的参数,而这个参数说明按压多长时间, duration 是以毫秒为单位,1000表示为一秒钟,其他的方法都和 press() 的方法相同
def long_press(self, el=None, x=None, y=None, duration=1000):
"""
Begin a chain with a press down that lasts `duration` milliseconds
"""
self._add_action('longPress', self._get_opts(el, x, y, duration))
return self
例:
TouchAction(driver).long_press(x=0, y=400, duration=1000)
点击使用的方法 :tap() 对一个元素或者控件执行点击操作
def tap(self, element=None, x=None, y=None, count=1):
"""
Perform a tap action on the element
:Args:
- element - the element to tap
- x - (optional) x coordinate to tap, relative to the top left corner of the element.
- y - (optional) y coordinate. If y is used, x must also be set, and vice versa
:Usage:
"""
opts = self._get_opts(element, x, y)
opts['count'] = count
self._add_action('tap', opts)
return self
例:
TouchAction(driver).tap(x=0, y=400, count=2)
移动的方法:move_to() 将手指从一个点移动到指定的元素或者点的位置(移动到目标位置有时是算绝对坐标点,有时是基于前面一个坐标点的偏移量,这个如何计算要根据具体的App来进行计算)
def move_to(self, el=None, x=None, y=None):
"""
Move the pointer from the previous point to the element or point specified
"""
self._add_action('moveTo', self._get_opts(el, x, y))
return self
例:
TouchAction(driver).moveTo(1, 302).perform().release()
暂停的方法:wait() 暂停脚本的执行,单位为毫秒
def wait(self, ms=0):
"""
Pause for `ms` milliseconds.
"""
if ms is None:
ms = 0
opts = {'ms': ms}
self._add_action('wait', opts)
return self
例:
TouchAction(driver).wait(1000).perform().release()
启动随手记App,进行操作后进入到手势密码界面,在九宫格界面滑动设置密码,执行2次
MacBook Air / Windows | Python 3.6.2 | Appium 1.13.0 |
测试 随手记App Android V10.5.6.0 | 网易MuMu模拟器 Android6.0.1 |
ssj_touch_action.py
# -*- coding:utf-8 -*-
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support.ui import WebDriverWait
from time import sleep
xg_caps = {}
xg_caps['platformName'] = 'Android'
xg_caps['platformVersion'] = '6.0.1'
xg_caps['deviceName'] = '127.0.0.1:622471'
xg_caps['appPackage'] = 'com.mymoney'
xg_caps['appActivity'] = 'com.mymoney.biz.splash.SplashScreenActivity'
xg_caps['noReset'] = True
# 当send_keys输入中文时,需要配置下面两项内容,让Appium的输入法守护来执行相应的输入操作
xg_caps['unicodeKeyboard'] = True
xg_caps['resetKeyboard'] = True
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', xg_caps)
driver.implicitly_wait(5)
driver.find_element_by_id('com.mymoney:id/splash_skip_tv').click()
driver.find_element_by_id("com.mymoney:id/nav_setting_btn").click()
WebDriverWait(driver, 3).until(lambda x:x.find_element_by_id('com.mymoney:id/content_container_ly'))
# 这个地方也可以用 swipe 操作来滑动
TouchAction(driver)\
.press(x=246, y=422)\
.move_to(x=253, y=246)\
.release()\
.perform()
# 点击高级
driver.find_element_by_android_uiautomator('new UiSelector().text("高级")').click()
# 点击密码与手势密码
driver.find_element_by_id('com.mymoney:id/password_protected_briv').click()
# 点击手势密码保护,进入到手势页面
driver.find_element_by_id('com.mymoney:id/lock_pattern_or_not_sriv').click()
# 绘制手势密码
for i in range(2):
TouchAction(driver)\
.press(x=136.6, y=263.7).wait(2000)\
.move_to(x=269.5, y=263.7).wait(1000)\
.move_to(x=399.2, y=263.7).wait(1000)\
.move_to(x=139.6, y=378.6).wait(1000)\
.move_to(x=139.6, y=529.4).wait(1000)\
.move_to(x=274.5, y=524.4).wait(1000)\
.move_to(x=270.5, y=390.5).wait(1000)\
.move_to(x=408.5, y=394.5).wait(1000)\
.move_to(x=410.5, y=532.5).wait(1000)\
.release()\
.perform()