1. 程式人生 > >Appium常用操作之「元素定位、swipe 滑屏操作」

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

### 堅持原創輸出,點選藍字關注我吧 ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027161036.png) 作者:清菡
部落格: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 用這個工具來給大家定位: ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027153919.png) ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027153930.png) 實現一個截圖(通常情況下這樣用,可以截圖成功)。 ## 二、Appium 常用操作 ### 1.用 layui 做 app 元素定位的時候會報錯怎麼辦? 建議不用 `layui`。`layui` 在有些情況下定位元素是有問題的。在環境基本上是正確的情況下,它截圖截不到。所以可以捨棄 `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。 ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027143350.png) 可以找到,但是不代表這個東西出來了。 如果有明確元素的時候,就不要用`time.sleep`了。就等到元素出現,再去操作元素。 這個元素定位和 Web 元素定位一樣的,有多種方式。 安卓和 ios 的手機螢幕有大小的限制,所以一個頁面當中元素不會太多,也不會很密密麻麻。因為它需要你不但要能看得清楚還能用手點得著。所以它會做的格局上面內容偏少,間距也會比較大。 點選`“我的”`後,頁面內容切換。`頁面內容切換,你就要等,它也是要載入時間的。` ## 三、開啟 app 並登入 ```PYTHON # 某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 兩種裝置同時通用。 ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027143333.png) 從一個點滑到另外一個點,那麼每個點都有 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 返回視窗的寬和高。` ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027143322.png) #### get_window_size()這個函式的返回值: 返回的是個字典。 ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027143310.png) ### 5.這個東西想一口氣把它滑過來,不能出現滑動到半路上又回去了。如果我要從右邊滑到左邊,起點和終點怎麼選? `swipe`有 2 個座標點,首先要得到`start_x`。 x 軸是`width`。`size['width']`是 x 軸的最大值。 **所有人的使用習慣:** 滑屏都是在正中間滑屏或者稍微偏下一點。從一個頁面滑動到另外一個頁面,y 軸沒有變化。 #### 所以 y 值是固定的,就取箇中間值 0.5: ```PY #height、width size= driver.get_window_size() start_x=size['width']*0.9 start_y=size['height']*0.5 ``` #### 滑動的間距最好是達到 80%以上,這樣寫,間距就是 0.8 了: ```PYTHON #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 或者安卓,那就只能在對應的平臺上使用。 `如果一個函式並沒有說明,那麼就是大家一起用的,不分彼此。` ```PY #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+原創文章,歡迎關注、交流,禁止第三方擅自轉載。 ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201027160748.jpg) 感謝支援清菡原創,歡迎點選在看和轉發!