Appium常用操作之「元素定位、swipe 滑屏操作」

清菡發表於2020-10-30

堅持原創輸出,點選藍字關注我吧

作者:清菡

部落格:oschina、雲+社群、知乎等各大平臺都有。

目錄

  • 一、開啟 uiautomatorviewer
  • 二、Appium 常用操作
    • 1.用 layui 做 app 元素定位的時候會報錯怎麼辦?
    • 2.不等待,直接去找這個元素會報錯嗎?
    • 3.如果是 Web 自動化,會 import By,在 Appium 中 MobileBy 有 8 種定位方式。如果現在還用 By,就沒辦法用到 uiautomator 以及 accessibility_id。
    • 4.如果是歡迎頁面,沒有這種元素的怎麼辦?
  • 三、開啟 app 並登入
  • 四、移動端特有的操作
    • 1.swipe 滑屏操作
    • 2.如果寫一個操作,所有的手機都能適用,是不是應該考慮螢幕的尺寸呢?
    • 3.有沒有什麼辦法可以獲取整個裝置的尺寸大小?
    • 4.螢幕的 size 怎麼獲取呢?
    • 5.這個東西想一口氣把它滑過來,不能出現滑動到半路上又回去了。如果我要從右邊滑到左邊,起點和終點怎麼選?
    • 6.準備花多長時間去滑動呢?

一、開啟 uiautomatorviewer

用這個工具來給大家定位:

實現一個截圖(通常情況下這樣用,可以截圖成功)。

二、Appium 常用操作

1.用 layui 做 app 元素定位的時候會報錯怎麼辦?

建議不用 layuilayui 在有些情況下定位元素是有問題的。在環境基本上是正確的情況下,它截圖截不到。所以可以捨棄 layui,直接用自帶的 uiautomatorviewer(現在擁有的定位方式,它全部都支援)。

2.不等待,直接去找這個元素會報錯嗎?

和 Web 自動化一樣,Appium 執行這個命令也是需要時間的。這一行程式碼,是進入到 app 當中,app 在這個過程中做一件事(一堆的東西),所以即便你執行的這隻有這一行程式碼,它做的事比較多。

感覺上比 Web 等待的時間要長,但是如果你是用真機的話比用模擬器快。

所以這個之前需要等待一下。在 Web 自動化等待的時候用的是這個WebDriverWait以及EC條件表達。在這裡也是一樣,因為都是要頁面等待元素出現,等待元素可見。

3.如果是 Web 自動化,會 import By,在 Appium 中 MobileBy 有 8 種定位方式。如果現在還用 By,就沒辦法用到 uiautomator 以及 accessibility_id。

所以在移動端當中程式碼:

from selenium.webdriver.common.by import By

要改成:

from appium.webdriver.common.mobileby import MobileBy

再也不需要用By了,By有的id、class,它都有的。所以,在這個地方要等到這個id出現,那就是:

WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ID,'com.huyu.yuncaidian:id/id_text')))

這個是開啟 app 之後一定要做的等待工作。

4.如果是歡迎頁面,沒有這種元素怎麼辦?

如果預設進入的就是歡迎介面,要我們左滑右滑的這種,那就sleep因為你沒有可識別的元素。

通過 Activity 的名字來識別沒有用,因為它也叫 Activity。

可以找到,但是不代表這個東西出來了。

如果有明確元素的時候,就不要用time.sleep了。就等到元素出現,再去操作元素。

這個元素定位和 Web 元素定位一樣的,有多種方式。

安卓和 ios 的手機螢幕有大小的限制,所以一個頁面當中元素不會太多,也不會很密密麻麻。因為它需要你不但要能看得清楚還能用手點得著。所以它會做的格局上面內容偏少,間距也會比較大。

點選“我的”後,頁面內容切換。頁面內容切換,你就要等,它也是要載入時間的。

三、開啟 app 並登入

#  某app 2.9.0準環境
from appium import webdriver
import time
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.mobileby import MobileBy

desired_caps={}
# 平臺型別
desired_caps["platformName"]="Android"
# 平臺版本號
desired_caps["platformVersion"]="7.0"
# 裝置名稱
desired_caps["deviceName"]="XPUDU17713003790"
# app 包名
desired_caps["appPackage"]="保密"
# app 入口 acitivity
desired_caps["appActivity"]="保密"

# 連線Appium server。前提:appium desktop要啟動。有監聽埠。
# 將desired_caps傳送給appium server。開啟app
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)

# 執行程式碼之前:
#1.appium server啟動成功。處於監聽狀態
#2.模擬器/真機必須能夠被電腦識別。即adb devices能夠識別到要操作的裝置。


# 點選“我的”
time.sleep(5)
# 元素定位-組合定位方式
driver.find_element_by_xpath("//*[@resource-id='com.tfffc.cf:id/id_text' and @text='我的']").click()

#點選手機密碼登入
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ID,'com.tfffc.cf:id/tv_phone_passwad')))
driver.find_element_by_id('com.tfffc.cf:id/tv_phone_passwad').click()

#輸入使用者名稱、密碼、點選登入按鈕
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ID,'com.tfffc.cf:id/editview_phone')))
driver.find_element_by_id('com.tfffc.cf:id/editview_phone').send_keys('輸入手機號')
driver.find_element_by_id('com.tfffc.cf:id/editview_phone_password').send_keys('輸入密碼')
driver.find_element_by_id('com.tfffc.cf:id/phone_password_login').click()

四、移動端特有的操作

1.swipe 滑屏操作

Appium 的swipe函式是針對螢幕上的座標來滑動的。
swipe函式是安卓和 IOS 兩種裝置同時通用。

從一個點滑到另外一個點,那麼每個點都有 x 值和 y 值。swipe有 4 個引數。所以起始 x,起始 y,結束 x,結束 y。

2.如果寫一個操作,所有的手機都能適用,是不是應該考慮螢幕的尺寸呢?

手機有 5 寸、4.4 寸、5.7 寸的。解析度是 1280x700,所以它最大的座標點就是 1280x700。不同的安卓廠商、不同的大小,它的解析度都不一樣,它的座標值是絕對不一樣的。

這個怎麼辦?怎麼相容下這個特徵比較好?

不需要針對每個版型的手機寫一段程式碼,全部通用。

用座標有個缺陷:可能適用於某一種手機,換個手機就不行了,因為座標值對不上。

3.有沒有什麼辦法可以獲取整個裝置的尺寸大小?

直接獲取下它的寬和高是多少。針對螢幕上的某個座標點來滑動的,又不是針對某一個元素。整屏滑動就是左滑右滑,上滑下滑。

設定下滑動的百分比,如果滑動40%-50%,感覺根本滑動不過去。如果能夠獲取到整屏的大小,按百分比來滑動,滑動的距離在70%-90%,那肯定就能滑過去了。

根據每個手機的 x 軸和 y 軸,確定它的滑屏百分比,那隨便什麼樣的手機都是可以滑屏的。所以在實現這個滑屏的時候,首先獲取螢幕的size

4.螢幕的 size 怎麼獲取呢?

有個專門的函式:

get_window_size 返回視窗的寬和高。

get_window_size()這個函式的返回值:

返回的是個字典。

5.這個東西想一口氣把它滑過來,不能出現滑動到半路上又回去了。如果我要從右邊滑到左邊,起點和終點怎麼選?

swipe有 2 個座標點,首先要得到start_x

x 軸是widthsize['width']是 x 軸的最大值。

所有人的使用習慣: 滑屏都是在正中間滑屏或者稍微偏下一點。從一個頁面滑動到另外一個頁面,y 軸沒有變化。

所以 y 值是固定的,就取箇中間值 0.5:

#height、width
size= driver.get_window_size()
start_x=size['width']*0.9
start_y=size['height']*0.5

滑動的間距最好是達到 80%以上,這樣寫,間距就是 0.8 了:

#height、width
size= driver.get_window_size()
start_x=size['width']*0.9
start_y=size['height']*0.5

end_x=size["width"]*0.1

swipe還有個引數叫做duration(時長),這個單位是毫秒

6.準備花多長時間去滑動呢?

看過手機的操作,如果滑動的太快了,根本沒有效果。有的時候滑動的太快了,它還沒來得及響應就結束了。所以可以設定下duration(時長),放緩一點呢,相對來說更穩定些。

向上向下滑動的時候,start_x 是?

上下滑動,x 軸不變,x 軸同樣取中間值。但是 y 軸從下往上,值越來越小。

這個可以把它封裝起來,以後需要的時候直接呼叫就好了,隨便什麼裝置都是一樣的。如果webdriver中有些方法標明瞭僅僅是 ios 或者安卓,那就只能在對應的平臺上使用。

如果一個函式並沒有說明,那麼就是大家一起用的,不分彼此。

#height、width
size= driver.get_window_size()
start_x=size['width']*0.9
start_y=size['height']*0.5

end_x=size["width"]*0.1
end_y=size['height']*0.5
#從右向左滑
driver.swipe(start_x,start_y,end_x,end_y,200)
#從左向右滑
driver.swipe(end_x,end_y,start_x,start_y,200)

#向下滑動
#向上滑動:x軸不變,y從大到小
driver.swipe(size["width"]*0.5,size["heigth"]*0.9,size["width"]*0.5,size["heigth"]*0.1)
#向上滑動:x軸不變,y從小到大
driver.swipe(size["width"]*0.5,size["heigth"]*0.1,size["width"]*0.5,size["heigth"]*0.9)

公眾號清菡軟體測試首發,更多原創文章:清菡軟體測試 94+原創文章,歡迎關注、交流,禁止第三方擅自轉載。

感謝支援清菡原創,歡迎點選在看和轉發!

相關文章