在的自動化測試過程中不可能只測試一個固定的有限界面,有的時候會遇到一些比較長的頁面,這個時候就會用到滑動的操作,在 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)
*/
1、Swipe 的分類
- 水平滑動
- 垂直滑動
- 任意方向滑動
滑動的軌跡圖有:
2、綜合案例:
-
測試場景
- 啓動 豌豆莢,進入到 精選 界面
- 水平手動向左滑動2次
-
執行腳本
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()
3、Touch Action 操作:
swipe 的滑動操作一般是在兩個點之間的滑動,但是呢,在實際的自動化測試過程中可能會遇到一些多點連續滑動操作,比如常用的九宮格解鎖、遊戲中在屏幕上控制方向的方向標、連續拖動圖片等
-
Touch Action 包含的操作:
按壓 | 釋放 | 執行 | 長按 |
點擊 | 移動 | 暫停 |
要完成這一系列的動作,需要導入appium中的 Touch Action 模塊:
from capability import driver
from appium.webdriver.common.touch_action import TouchAction
3.1 按壓、釋放、執行
按壓使用的方法是: 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()
3.2 長按
長按使用的方法: 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)
3.3 點擊
點擊使用的方法 :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)
3.4 移動
移動的方法: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()
3.5 暫停
暫停的方法: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()
4、九宮格綜合應用
-
測試場景
啓動隨手記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()
-
測試結果