移動端 UI自動化測試學習之Appium框架(包含adb調試工具介紹)

文章目錄

  • 前言
  • adb調試工具
    • adb組成
    • 常用命令
      • 獲取程序的包名和界面名
      • 文件傳輸
        • 發送文件到手機
        • 從手機中拉取文件
      • 獲取app啟動時間
      • 獲取手機日志
      • 其他命令
  • Appium 簡介
    • 工作原理圖
  • 環境搭建
    • 安裝客戶端庫(appium lib)
    • 安裝Appium Server
    • 安裝JDK(自行下載并安裝)
    • 安裝 Android SDK
    • 連接手機
      • 運行相關APP
    • 連接手機模擬器
  • Appium基礎操作
    • 通過代碼啟動應用
    • 應用跳轉
    • 獲取app的包名和界面名
    • 關閉app和關閉驅動
    • 安裝和卸載應用
    • 將應用置于后臺
  • Appium元素定位
    • 界面元素查看工具
      • uiautomateviewer
      • Appium Inspector
        • 配置Desired Capabilities
        • Inspector界面說明
    • 定位方法(僅介紹常用方法)
      • id定位
      • CLASS NAME
      • ACCESSIBILITY ID
      • Xpath
        • 唯一屬性定位
        • 模糊匹配定位
        • 組合定位
        • 相對路徑搭配屬性
      • 安卓 UIAutomator
        • text定位
        • text模糊定位
        • text正則匹配定位
        • resourceId定位
        • resourceId正則匹配定位
        • className定位
        • className正則匹配定位
        • 組合定位
      • 查找多個元素
      • 隱式等待與顯示等待
      • 注意點
  • 元素操作
    • 獲取信息
    • 鍵盤輸入
    • 模擬觸控
      • 模擬點擊
      • 輕敲
      • 按下和抬起
      • 等待
      • 模擬長按
      • 移動
      • 多點觸控
    • 獲取toast
    • 滑動
      • swipe 滑動事件
      • scroll
      • drag_and_drop
      • 滑動和拖拽事件的選擇
  • 手機操作api(獲取手機分辨率、截圖、手機網絡、通知欄)
    • 模擬按鍵
  • Appium結合PO設計模式、數據驅動、Pytest、jenkins(參考Web端的博客,或自行查閱資料)
  • 參考目錄


前言

閱讀本文前請注意最后編輯時間,文章內容可能與目前最新的技術發展情況相去甚遠。歡迎各位評論與私信,指出錯誤或是進行交流等。


adb調試工具

ADB 全稱為 Android Debug Bridge,起到調試橋的作用,是一個客戶端-服務器端程序。其中客戶端是用來操作的電腦,服務端是 Android 設備

ADB 也是 Android SDK 中的一個工具,可以直接操作管理 Android 模擬器或者真實的 Android 設備。

adb組成

adb包含三個部分:
1.Client端:運行在開發機器中,即你的開發電腦,用來發送adb命令;
2.Daemon守護進程:運行在調試設備中,手機或模擬器,用來接收并執行adb命令;
3.Server端:同樣運行在開發機器中,用來管理Client端和手機的Daemon之間的通信。

在這里插入圖片描述
1.client端將命令發送給server端
2.server端會將命令發送給daemon端
3.daemon端進行執行
4.將執行結果,返回給server端
5.server端將結果再返回給client端

常用命令

獲取程序的包名和界面名

1.包名(package):決定程序的唯一性(不是應用的名字)
2.界面名(activity):可以理解為,一個界面名,對應著一個界面。

應用場景:
自動化測試需要通過代碼的形式告訴手機測試哪個應用程序的哪一個界面,所以需要通過這個命令進行獲取。

使用步驟
1.打開需要測試的應用程序
2.在電腦的終端輸入adb命令(電腦已經與移動設備連接)

# Mac/Linux:
adb shell dumpsys window windows | grep mFocusedApp
# Windows:
adb shell dumpsys window windows | findstr mFocusedApp

在這里插入圖片描述
上圖中 打開了手機的設置,包名:com.android.settings 界面名:.Settings

文件傳輸

發送文件到手機

應用場景
將手機需要的數據、文件 在電腦上調整好,直接發送給手機

命令格式

adb push 電腦的文件路徑 手機的文件夾路徑
# 示例 將桌面的a.txt發送到手機的sd卡
adb push c:\users\hm\besktop\a.txt /sdcard
從手機中拉取文件

應用場景
將手機產生的文件(數據庫文件,日志文件)拉取到電腦中

命令格式

adb pull 手機的文件路徑 電腦的文件夾路徑# 示例 將手機的sd卡的a.txt拉取到桌面
adb pull /sdcard/a.txt C:\users\hm\besktop

獲取app啟動時間

應用場景
1.如果企業對應用程序的啟動速度有要求,則需要使用這個命令進行測試
2.測試標準:參照同類軟件,啟動時間不能超出一倍即可

命令格式

adb shell am start -w 包名/啟動界面名# 示例 啟動 com.android.settings程序并且進入主界面(.Settings)adb shell am start -w com.android.settings/.Settings

在這里插入圖片描述

在這里插入圖片描述

獲取手機日志

應用場景
將bug的日志信息發送給開發人員,便于開發人員定位bug

使用步驟
1.打開需要測試的應用程序
2.找到觸發bug的位置
3.使用查看日志命令
4.觸發bug
5.獲取日志信息

命令格式

adb logcat

其他命令

adb install 路徑/xx.apk # 安裝app 到手機adb uninstall 包名 # 卸載手機上的app,需要指定包名adb devices # 獲取當前電腦已經連接設備和對應的設備號adb shell # 進入到安卓手機內部的linux系統命令行中adb start-server # 啟動adb服務端,出bug時使用可以重啟服務器,先關閉再啟動adb kill-server # 停止adb服務端,出bug時使用可以重啟服務器,先關閉再啟動adb --help # 查看adb幫助,命令記不清楚時有用

Appium 簡介

Appium 是一個移動 App 自動化框架。
能夠完成的任務:

  • 自動化完成一些重復性的任務
  • 比如微信客服機器人
  • 爬蟲
  • 自動化測試

Appium 自動化方案的特點:

  • 開源免費
  • 支持多個平臺
    Appium支持Android和iOS平臺的自動化測試,使用相同的API可以編寫跨平臺的測試腳本。
  • 支持多種類型的自動化
    無論是原生移動應用(APP)、混合應用(Hybrid App)和移動網頁應用(H5),Appium都支持自動化測試。
  • 支持多種編程語言
  • 使用標準的WebDriver協議
    Appium使用WebDriver協議來與移動設備進行通信,這使得開發人員可以使用熟悉的API和命令,無需學習新的測試框架。

工作原理圖

在這里插入圖片描述

包含了 3個主體部分 : 自動化程序、Appium Server、移動設備

  1. 自動化程序
    自動化程序是程序員開發的,實現具體的 手機自動化 功能。
    要發出具體的指令控制手機,需要使用 客戶端庫。
    和Selenium一樣,Appium 組織 也提供了多種編程語言的客戶端庫,包括 java,python,js, ruby等,方便不同編程語言的開發者使用。
    我們需要安裝好客戶端庫,調用這些庫,就可以發出自動化指令給手機。

  2. Appium Server
    Appium Server 是 Appium 組織開發的程序,它負責管理手機自動化環境,并且轉發 自動化程序的控制指令 給 手機,并且轉發 手機給 自動化程序的響應消息。

  3. 設備
    這里說的設備,不僅僅是手機,包括所有 蘋果、安卓的移動設備,比如:手機、平板、智能手表等。
    為了直觀方便的講解,這里我們簡稱: 手機
    設備為什么能 接收并且處理自動化指令呢?
    因為,Appium Server 會在手機上 安裝一個 自動化代理程序, 代理程序會接收自動化指令,并且執行自動化指令

比如:要模擬用戶點擊界面按鈕,Appium 自動化系統的流程是這樣的:
1.自動化程序 調用客戶端庫相應的函數, 發送 點擊元素 的指令(封裝在HTTP消息里)給 Appium Server
2.Appium Server 再轉發這個指令給 手機上的自動化代理
3.手機上的自動化代理 接收到 指令后,調用手機平臺的自動化庫,執行點擊操作。返回點擊成功的結果給 Appium Server
Appium Server 轉發給 自動化程序
4.自動化程序了解到本操作成功后,繼續后面的自動化流程

自動化代理控制,使用的什么庫來實現自動化的呢?
如果測試的是蘋果手機, 用的是蘋果的 XCUITest 框架 (IOS9.3版本以后)
如果測試的是安卓手機,用的是安卓的 UIAutomator 框架 (Android4.2以后)
這些自動化框架提供了在手機設備上運行的庫,可以讓程序調用這些庫,像人一樣自動化操控設備和APP,比如:點擊、滑動,模擬各種按鍵消息等。

環境搭建

安裝客戶端庫(appium lib)

根據原理圖, 我們知道自動化程序需要調用客戶端庫和 Appium Server 進行通信。

因為我們介紹Python語言的客戶端庫,使用以下命令進行安裝。

pip install appium-python-client

手動下載方式:
appium lib,下載地址:http://appium.io/downloads.html
選擇Python版本的Lib 例如 Appium-Python-Client-0.22.tar.gz

其他依賴(自行下載并安裝)
python, 下載地址:https://www.python.org/
Appium依賴于Selemium,所以還要下載 Selemium Lib: selenium-2.53.2.tar.gz https://pypi.python.org/pypi/selenium

安裝Appium Server

下載地址:http://appium.io/
根據自己的OS進行安裝程序的選擇
直接打開下載完成的安裝程序,一直下一步即可。
在這里插入圖片描述

其他依賴(自行下載并安裝)
nodejs,下載地址:https://nodejs.org/en/

安裝JDK(自行下載并安裝)

要對安卓APP進行自動化測試,必須要安裝安卓SDK,而安卓SDK需要 JDK 環境。

安裝 Android SDK

對于安卓APP的自動化,Appium Server 需要 Android SDK。
因為要用到里面的一些工具,比如 要執行命令 設置手機、傳送文件、安裝應用、查看手機界面等。
下載地址:http://developer.android.com/sdk/index.html,下載sdk tools
國內下載地址:http://www.androiddevtools.cn/
下載最新的 Android SDK文件包: androidsdk.zip ,并且解壓,即可。
解壓完成后,需要 配置一下 添加一個 環境變量 ANDROID_HOME ,設置值為sdk包解壓目錄,比如 d:\tools\androidsdk
另外,還推薦大家再添加一個 環境變量 ,加入 adb所在目錄, d:\tools\androidsdk\platform-tools

如果是通過Android SDK Manage來下載 Android SDK包的話, 可參考
https://austin.blog.csdn.net/article/details/126364649

連接手機

上述的軟件環境都準備好以后
啟動 appium 服務器
在這里插入圖片描述
進入 手機設置 -> 關于手機 ,不斷點擊 版本號 菜單(7次以上),
退出到上級菜單,在開發者模式中,啟動USB調試
(注:不同手機這里打開方式不一樣,一般手機在【關于手機】里找到【版本號】,連續點擊【版本號】7次,即可進入開發者模式。
在這里插入圖片描述
在這里插入圖片描述

在你運行程序的電腦上 用 USB線 連接上 你的安卓手機
手機界面彈出 類似 如下提示。

在這里插入圖片描述
選擇 允許USB調試。

注意:
有的手機系統,可能需要一些額外的設置。
比如,有的手機,開發者選項里 需要打開 允許通過USB安裝應用 等。

連接好以后,打開CMD命令行窗口, 執行 adb devices 命令來列出連接在電腦上的安卓設備。
輸出手機的deivce id
在這里插入圖片描述
表示電腦上可以查看到 連接的設備,隨后就可以運行自動化程序了。

device id 可以在手機的【設置】中的【狀態消息】可以查到。
在這里插入圖片描述
在這里插入圖片描述
注:如果出現device not found,優先檢查手機的驅動是否安裝正確,也可以到硬件管理器中去查看對應的設備驅動是否異常。
這里推薦使用adb driver installer這個軟件來安裝對應的設備驅動,網上很多的,隨便百度一下都有下載。

如果像圖中顯示出現了多個設備連接,其中一個的端口是5555 的話,后續的一些操作可以指定對應的device id去進行操作,比如 adb -s XXXXXX(device id) shell 來進行操作。

運行相關APP

我們想要通過Appium來運行相關APP,還需要獲取與APP相關的幾個參數。

appPackage:包名,在Android系統中是判斷一個App的唯一標識。
appActivity:界面名。
platformName:設備的平臺名,Android或iOS。
deviceName:設備名,這里填入剛才ADB里的device id即可。

以下為獲取appPackage與appActivity的幾種方法。

  1. 查看源代碼
    如果被測對象是自研的APP,直接問下對應開發同學,這兩個參數的值就可以

  2. 使用ADB
    在手機連接的狀態下,先打開想操作的APP,之后在cmd中輸入adb shell "dumpsys window | grep mCurrentFocus"即可查看對應APP的appPackage了。如果有多個設備,則需要先用adb -s XXXX shell來制定進入的設備,再輸入dumpsys window | grep mCurrentFocus查看即可。

紅框處的就是appPackage。但這里需要注意,因為你進入APP后可能會進行其他操作,所以當前APP所在的頁面不一定是啟動頁面,所以appActivity的值不一定是對的。
在這里插入圖片描述
使用monkey命令來進行appActivity的獲取,使用命令adb shell monkey -p com.xxxxxxx(appPackage) -vvv 1來進行獲取。
在這里插入圖片描述

連接手機模擬器

關于手機模擬器如何下載安裝 請各位自行查閱資料
以學習通為測試對象,打開雷電模擬器,下載學習通。然后啟動學習通,登錄進入主頁面。

啟動雷電模擬器
在這里插入圖片描述
在這里插入圖片描述
啟動Appium
在這里插入圖片描述
點擊右上角的搜索符號,開啟Appium Server。
在這里插入圖片描述
這里需要編輯一個用于連接模擬器并打開學習通的參數配置(Desired Capabilities),具體有四個核心的參數,分別為platformName,deviceName,appPackage,appActivity。
在這里插入圖片描述
在這里插入圖片描述
由于雷電模擬器是Android,所以platformName為Android

win+R鍵打開cmd窗口,輸入adb devices,結果如圖所示,所以deviceName即為emulator-5554,也就是雷電模擬器的設備名。
在這里插入圖片描述

adb shell dumpsys activity | findstr "mResume" # Android 8.1之下版本使用
adb shell dumpsys activity | findstr "mFocus"

查看學習通應用的appPackage和appActivity(必須保證雷電模擬器的學習通應用程序處于開啟狀態)如圖所示。appPackage為com.chaoxing.mobile,appActivity為.main.ui.MainTabActivity
在這里插入圖片描述
所以最終配置如下:
在這里插入圖片描述
這里多設置了一個noReset,這個參數表明不停止應用程序和清除應用程序數據。

點擊Start Session,等待一段時間(Appium會驅動雷電模擬器重啟學習通,如果學習通處于黑屏狀態導致連接失敗,退出學習通,重新點擊Start Session連接一次應該就可以了)如果出現以下界面,表示連接成功。

在這里插入圖片描述

Appium基礎操作

注意:進行這些操作前 已啟動appium server 并 已連接設備/模擬器

通過代碼啟動應用

from appium import webdriver
desiredcaps = dict()
#啟動配置參數
desired_caps['platformName'] = 'Android' # 平臺為安卓
desired_caps['platformversion'] = '5.1' # 安卓版本
desiredcaps['deviceName'] = '192.168.56.101:5555' # 設備名 由adb命令獲取
#應用參數
desired_caps['apppackage'] = 'com.android.settings' # 某個應用的包名
desired_caps['appActivity'] = '.Settings' # 應用的界面名
#獲取driver 地址為appium server的地址
driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
#退出driver
driver.quit()

應用跳轉

應用場景

如果一個應用需要跳轉到另外一個應用,就可以使用這個api進行應用的跳轉,就像我們通過外賣應用下訂單之后會跳轉到支付應用一樣。

# 腳本內啟動其他app
# 參數:
# apppackage:要打開的程序的包名
# appActivity:要打開的程序的界面名
driver.start_activity(apppackage,appActivity)

獲取app的包名和界面名

# 獲取屬性
drive.current_packagedrive.current_activity

關閉app和關閉驅動

# 關閉當前操作的app,不會關閉驅動對象
driver.close_app()
#關閉驅動對象,同時關閉所有關聯的app
driver.quit()

安裝和卸載應用

# 安裝app
# app_path:apk路徑
driver.install_app(app_path)# 卸載app
# app_id:應用程序包名
driver.remove_app(app_id)# 判斷app是否已經安裝
# app_id:應用程序包名
#返回值:
# 布爾類型,True為安裝,False為沒有安裝driver.is_app_installed(app_id)

將應用置于后臺

應用場景
銀行類app會在進入后臺一定時間后,再回到前臺頁面會重新輸入密碼,如果需要自動化測試這種功能,可以使用這個api進行測試

# app放置到后臺一定時間后再回到前臺,模擬熱啟動
# seconds:后臺停留多少秒
driver.background_app(seconds)

Appium元素定位

和Selenium Web自動化一樣,要操作界面元素,必須先 定位元素。

Appium是基于Selenium的,所以 和 Selenium 代碼 定位元素的 基本規則相同:
find_element_by_XXX 方法,返回符合條件的第一個元素,找不到拋出異常
find_elements_by_XXX 方法,返回符合條件的所有元素的列表,找不到返回空列表
通過 WebDriver 對象調用這樣的方法,查找范圍是整個界面
通過 WebElement 對象調用這樣的方法,查找范圍是該節點的子節點

界面元素查看工具

做 Selenium Web 自動化的時候,要找到元素,我們是通過瀏覽器的開發者工具欄來查看元素的特性,根據這些特性(屬性和位置),來定位元素

Appium 要自動化手機應用,同樣需要工具查看界面元素的特征。
常用的查看工具是: Android Sdk包中的 uiautomateviewer 和 Appium Desktop 中的 Appium Inspector

uiautomateviewer

安卓查看APP界面元素,可以使用 Android SDK 中的工具 uiautomateviewer 。

使用步驟
1.進入SDK目錄下的目錄
mac在tools/bin 目錄下,打開 uiautomatorviewer
windows在tools目錄下,打開 uiautomatorviewer.bat
2.電腦連接真機或打開android模擬器
3.啟動待測試app
4.點擊uiautomatorviewer的左上角Device Screenshot(從左數第二個按鈕)
5.uiautomatorviewer上就會同步顯示啟動的app以及對應的頁面,在其內部點擊希望查看的控件
6.查看右下角Node Detail相關信息
在這里插入圖片描述
在這里插入圖片描述

Appium Inspector

Appium Desktop 中的 Appium Inspector 也可以查看元素。
(在某些版本中,需要去官網單獨下載安裝Inspector,參考 https://blog.csdn.net/NoamaNelson/article/details/134947987)
點擊放大鏡圖標來開啟Appium Server。

啟動后界面如下
在這里插入圖片描述

配置Desired Capabilities

要啟動APP就需要填寫對應APP的啟動參數。
通過右邊的加號來進行屬性的添加

在這里插入圖片描述
填入獲取的各項參數
在這里插入圖片描述
填寫完成后后邊會出現JSON格式的表示信息,然后點擊【Start Session】即可啟動APP。
在這里插入圖片描述
啟動時,會在測試手機上安裝Appiium的APP,啟動完成后手機會自動打開你要啟動的APP,并且在Inspector上顯示與APP同步的畫面。
在這里插入圖片描述

Inspector界面說明

在這里插入圖片描述
自左向右,依次為:

Native App Mode:切換為原生APP模式;

Web/Hybrid App Mode:切換為混合APP模式,如果APP有內有小程序(Uni App)或者H5的話可以試試這個模式;

Select Elements:選擇元素模式,在左側預覽窗口中鼠標的點擊模式會變成元素的選取,而不是模擬點擊的操作,類似于瀏覽器開發者工具中的選擇元素;

Swipe By Coordinates:使用坐標滑動,顧名思義,就是利用鼠標在A和B點分別進行點擊,之后會根據點擊的順序與方向進行相應方向的滑動動作模擬;

在這里插入圖片描述
Tap By Coordinates:使用坐標點擊,類似于現實中的點擊動作,用哪點哪,同步設備與預覽窗的畫面;

Back:退回上一步,類似手機的返回按鈕;

Refresh Source & Screenshot:刷新資源與截圖,一般在Select Element模式下用的比較多一點,在元素抓取的過程中如果需要查看功能互動或頁面跳轉的時候可以進行畫面的刷新操作,但Swipe By Coordinates與Tap By Coordinates模式下就用不太到了;

Start Recording:開始錄制,我們可以在打開這個選項后直接對APP的預覽畫面進行一些操作,Appium會自動幫我們把動作轉換成指定語言的相關代碼;

在這里插入圖片描述
該功能不太推薦測試同學使用,特別是已經有簡單代碼基礎的同學,它默認會使用xpath的定位方式。xpath的定位方式十分的脆弱,特別是絕對路徑定位,一旦發生變化,腳本的維護就會變得十分的困難,如果一定要用,推薦使用相對路徑的定位方法。

Search for element:搜索元素,我們可以根據各類元素的定位條件進行元素的相關搜索,方便我們快速定位。

在這里插入圖片描述
Copy XML Source to Clipboard:復制頁面元素,可以將該頁面中所有的元素信息復制。

Quit Session & Close Inspector:關閉會話且關閉Inspector。

當我們選中一個元素后,被選中的元素會顯示以下選項,自左向右依次為:
在這里插入圖片描述
Tap:模擬點擊;

Send Keys:如果為輸入框的話可以使用這個選項來填寫對應的內容;

在這里插入圖片描述
Clear:可以對編輯框內的內容進行清除;

Copy Attributes to Clipboard:將選中的元素相關信息復制到粘貼板中;

Get Timing:獲取選中的元素響應所需的時長。

在這里插入圖片描述

定位方法(僅介紹常用方法)

在Inspector獲取了APP界面元素的屬性之后,結合Python代碼根據屬性利用合適的定位方法來定位元素。

id定位

安卓應用元素的 id 或 resource-id 屬性,一般來說是唯一值,使用Inspector就可以定位到,查到值之后可以使用搜索查看下是否唯一。

在這里插入圖片描述
在這里插入圖片描述

# 方法已棄用
driver.find_element_by_id('expand_search')from appium import webdriver
from base.base_driver import driver_setup
from appium.webdriver.common.appiumby import AppiumBydriver = webdriver.Remote('http://localhost:4723/wd/hub', driver_setup())
# 方法已棄用
driver.find_element_by_id('com.tiffany.rta.debug:id/edt_customer_name')
# find_element用此方法
driver.find_element(AppiumBy.ID('com.tiffany.rta.debug:id/edt_customer_name'))

CLASS NAME

安卓界面元素的 class屬性 界面中相同class屬性的元素重復幾率較高, 通常不是唯一的。
一般根據class 屬性來選擇元素, 是要選擇多個而不是一個。
如果要查找的 界面元素的class屬性 在當前界面中只有一個,可以根據class 來唯一選擇。

在這里插入圖片描述

driver.find_elements_by_class_name('android.widget.TextView')driver.find_element(AppiumBy.CLASS_NAME('android.widget.EditText'))

ACCESSIBILITY ID

元素的 content-desc 屬性是用來描述該元素的作用的,類似于備注。

如果要查詢的界面元素有 content-desc屬性,我們可以通過它來定位選擇元素。

driver.find_element_by_accessibility_id('找人')driver.find_element(AppiumBy.ACCESSIBILITY_ID('這是一個按鈕'))

Xpath

Appium 也支持通過 Xpath選擇元素。
但是其可靠性和性能不如 Selenium Web自動化。因為Web自動化對Xpath的支持是由瀏覽器實現的,而Appium Xpath的支持是 Appium Server實現的。
介紹幾種常用的xpath定位方法方法。表達式的語法規則和 以前學習的Selenium里面Xpath的語法是一樣的

唯一屬性定位

如果頁面中屬性的text或id是固定且唯一的,可以使用以下方法。

# text屬性唯一
driver.find_element(AppiumBy.XPATH('//*[@text="顧客名稱"]'))

這里的 // 指的是相對路徑,* 代表匹配所有,@ 是查找對應的指定屬性,這里是通過text來定位的所以就在@后面填寫text,之后跟上具體的屬性值即可。

# id屬性唯一
driver.find_element(AppiumBy.XPATH('//*[@resource-id="com.tiffany.rta.debug:id/edt_customer_name"]'))# class屬性唯一
driver.find_element(AppiumBy.XPATH('//*[@class="android.widget.EditText"]'))
模糊匹配定位

與text中的模糊匹配類似,是在不太清楚具體xpath路徑時或具體值可能變動的情況下快速定位匹配的方法。

# 以text屬性為例,class、id方法類似
driver.find_element(AppiumBy.XPATH('//*[contains(@text="新增")]'))
組合定位
# id和text屬性
driver.find_element(AppiumBy.XPATH('//*[@resource-id="com.tiffany.rta.debug:id/edt_customer_name" and @text="顧客名稱"]'))
相對路徑搭配屬性
driver.find_element_by_xpath('//ele1/ele2[@attr="value"]')

注意:在appium中, xpath表達式中 每個節點名 是元素的class屬性值。

安卓 UIAutomator

根據id,classname, accessibilityid,xpath,這些方法選擇元素,其實底層都是利用了安卓 uiautomator框架的API功能實現的。

參考 谷歌安卓官方文檔介紹:https://developer.android.google.cn/training/testing/ui-automator

也就是說,程序的這些定位請求,被Appium server轉發給手機自動化代理程序,就轉化為為uiautomator里面相應的定位函數調用。

其實,我們的自動化程序,可以直接告訴 手機上的自動化代理程序,讓它 調用UI Automator API的java代碼,實現最為直接的自動化控制。

介紹比較常用的Uiautomator的定位方法:

text定位

在這里插入圖片描述

driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("請輸入顧客姓名")')
text模糊定位

定位text較長的元素時,就可以使用模糊匹配的方法textContains來進行元素的定位。

driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().textContains("姓名")')
text正則匹配定位
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().textMatches("^請輸入.*")')
resourceId定位
find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().resourceId("com.tiffany.rta.debug:id/edt_customer_name")')
resourceId正則匹配定位
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().resourceIdMatches(".+edt_customer_name")')
className定位
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().className("android.widget.EditText")')
className正則匹配定位
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().classNameMatches(".*EditText")')
組合定位
# id與text組合
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().resourceId("com.tiffany.rta.debug:id/edt_customer_name").text("顧客名稱")')# className與text組合
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().className("android.widget.EditText").text("顧客名稱")')

查找多個元素

與Selenium雷系,如果同一頁面中某一屬性有多個元素時,可以使用driver.find_elements的方法定位到多個元素,然后采用下標來指定想要操作的元素。

# 定義輸入框,畫面中共有3個輸入框
element = driver.find_elements(AppiumBy.CLASS_NAME('android.widget.EditText'))
# 指定第一個輸入框中輸入“張三”
element[0].send_keys("張三")

隱式等待與顯示等待

與Selenium同樣的,Appium也可以對元素設置隱式等待與顯示等待

隱式等待:所有定位元素的超時時間設置為同一個值,等待元素加載指定的時長,超出時長拋出NoSuchElementException異常
顯示等待:單獨對某元素的設置超時時間,等待元素加載指定的時長,超出時長拋出TimeoutException異常

# 隱式等待
driver.implicitly_wait(5);# 顯示等待
# 1.導包 請注意這里導的是selenium包
# 2.創建WebDriverWait對象
# 3.調用WebDriverWait對象的until方法
from selenium. webdriver . support . wait import webDriverwait
# 創建WebDriverwait對象 在5秒鐘內,每間隔1秒進行尋找元素
wait=webDriverwait(driver,5,poll_frequency=1)
#獲取元素并設置超時時間和頻率
element=wait.until(lambdax:x.findelementby-xpath("//*[contains(@content-desc,'收起')]“))

注意點

  • Android與iOS中元素定位的差異點在于,Android的元素如果不在當設備畫面中,比如需要上劃或者下劃才(swipe)能看見的元素,需要先做對應操作讓其展示出后才能進行元素的定位。而iOS則完全不需要如此操作;
  • 即使是id也不會絕對唯一,所以建議在定位元素前多用用Inspector中的元素搜索功能查看一下;
  • APP中某些元素是需要異步加載或執行的還是建議在定位元素之前加上等待時間,至于隱性還是顯性的結合著的測試業務與被測對象。
  • 注意同時導入了selenium、Appium包,selenium需要先導入。

元素操作

獲取信息

# 需要獲取按鈕、文本框、輸入框等控件的文本內容時使用
# 獲取element控件的文本內容
element = driver.find_element_by_id("com.android.settings:id/title")
print(element.text)# 獲取元素的位置
# 返回字典,X為元素的x坐標,y為元素的y坐標
print(element.locatian)
print(element.locatian["x"])
print(element.locatian["y"])# 獲取元素的大小
# 返回字典,width為寬度,height為告訴
print(element.size)
print(element.size["width"])
print(element.size["height"])# 獲取元素的屬性值
print(element.get_attribute("text"))

鍵盤輸入

在APP中一般都會存在信息輸入或交互框這類控件,如果需要往其中輸入對應的測試數據,就需要用到send_keys()函數。

driver.find_element(AppiumBy.ID, 'com.tiffany.rta.debug:id/edt_customer_number').send_keys('00127')
# 清除內容
driver.find_element(AppiumBy.ID, 'com.tiffany.rta.debug:id/edt_customer_number').clear()

如果要在控件中輸入中文的話,則需要在Desired Capabilities(啟動參數)中加入兩項參數

desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True

它們分別代表可以以unicode編碼格式進行輸入、初始化鍵盤狀態。

模擬觸控

模擬點擊

# 定位元素后 使用click()
driver.find_element(AppiumBy.ID, 'com.tiffany.rta.debug:id/edt_customer_number').click()

輕敲

#模擬手指對元素或坐標的輕敲操作
#參數:
# element:元素
# X:X坐標
# y:y坐標
# 需要導入appium.webdriver.common.touch_action下的TouchAction包
from appium.webdriver.common.touch_action import TouchAction
TouchAction(driver).tap(element=None,X=None,y=None).perform()示例 輕敲《設置》中的“WLAN”el=driver.findelement_by_xpath("//*[contains(@text,'WLAN')]")
TouchAction(driver).tap(e1).perform()

按下和抬起

#模擬手指對元素或坐標的按下操作
#參數:
# el:元素
# X:X坐標
# y:y坐標
TouchAction(driver).press(el=None,x=None,y=None).perform()#模擬手指對元素或坐標的抬起操作
TouchAction(driver).release().perform()示例
TouchAction(drive).press(x=650, y=650).perform()
TouchAction(drive).press(x=650, y=650).release().perform()

等待

# 模擬手指等待,比如按下后等待5秒之后再抬起。
# 參數:
# ms:暫停的毫秒數
TouchAction(driver).wait(ms=0).perform()# 按下指定定位的元素 停頓半秒再放開的操作
element = driver.find_element(AppiumBy.ID, 'com.tiffany.rta.debug:id/edt_customer_number')
TouchAction(drive).press(element).wait(500).release().perform()# 按住指定坐標的元素后停頓1秒再放開的操作
TouchAction(drive).press(x=120, y=120).wait(1000).release().perform()

模擬長按

#模擬手指對元素或坐標的長按操作
#參數:
# el:元素
# X:X坐標
# y:y坐標
# duration:長按時間,毫秒
TouchAction(driver).long_press(el=None,x=None,y=None,duration=1000).perform()element = driver.find_element(AppiumBy.ID, 'com.tiffany.rta.debug:id/edt_customer_number')
TouchAction(drive).long_press(element, duration=3000).perform()

移動

#模擬手指對元素或坐標的移動操作
#參數:
# el:元素
# X:X坐標
# y:y坐標
TouchAction(driver).move_to(el=None,x=None,y=None).perform()# 在初始坐標處按下 等待兩秒后 移動到 目標處 再放開
TouchAction(drive).press(x=120, y=120).wait(2000).move_to(x=350, y=120).release().perform()# move_to 可以連續使用
TouchAction(drive).press(x=120, y=120).move_to(x=350, y=120).move_to(x=450, y=220).release().perform()

多點觸控

如下圖,模擬雙指放大圖片
在這里插入圖片描述
實現步驟:
1.建立一個TouchAction,實現從坐標1到坐標2的拖動操作,但不要執行perform()方法
2.建立一個ToychAction,實現從坐標3到坐標4的拖動操作,但不要執行perform()方法
3.建立一個MultiAction類的對象,將兩個TouchAction對象加入到MultiAction的對象中
4.在MultiAction對象上執行perform()函數,同時觸發兩個TouchAction操作

from appium.webdriver.common.multi_action import MultiAction
from appium.webdriver.common.touch_action import TouchActionsize = driver.get_window_size()
x1, y1 = size['width'] * 0.2, size['height'] * 0.2  # 第一個手指的位置
x2, y2 = size['width'] * 0.8, size['height'] * 0.8  # 第二個手指的位置action = MultiAction(driver) \.add(TouchAction(driver).press(x=x1, y=y1).move_to(x=x1-50, y=y1-50).release()) \.add(TouchAction(driver).press(x=x2, y=y2).move_to(x=x2+50, y=y2+50).release()) \.perform()  # 執行動作

獲取toast

toast定義:
Android中的Toast是一種簡易的消息提示框。
當視圖顯示給用戶,在應用程序中顯示為浮動。和Dialog不一樣的是,它不會獲得焦點,無法被點擊。
Toast類的思想就是盡可能不引人注意,同時還向用戶顯示信息,希望他們看到。
而且Toast顯示的時間有限,Toast會根據用戶設置的顯示時間后自動消失。
在這里插入圖片描述
圖中的 用戶名或密碼錯誤,你還可以嘗試4次 就是 toast

toast = driver.find_element_by_xpath('//*[@text="用戶名或密碼錯誤,你還可以嘗試4次"]')

滑動

我們在做自動化測試的時候,有些按鈕是需要滑動幾次屏幕后才會出現,此時,我們需要使用代碼來模擬手指的滑動,也就是我們將要學習的滑動和拖拽事件

swipe 滑動事件

從一個坐標位置滑動到另一個坐標位置,只能是兩個點之間的滑動。

#從一個坐標位置滑動到另一個坐標位置,只能是兩個點之間的滑動
#參數:
# start_x:起點x軸坐標
# start_y:起點Y軸坐標
# end_x:終點X軸坐標
# end_y:終點Y軸坐標
# duration:滑動這個操作一共持續的時間長度,單位:ms
driver.swipe(start_x,start_y,end_x,end_y,duration=None)

scroll

#從一個元素滑動到另一個元素,直到頁面自動停止
# 參數:
# origin_el:滑動開始的元素
# destination_el:滑動結束的元素
driver.scroll(origin_el,destination_el)示例
從“存儲”滑動到“更多”
save_button=driver.findelement_by_xpath("//*[@text='存儲']")
more_button = driver.findelementby-xpath("//*[atext='更多']")
driver.scroll(save_button,more_button)

drag_and_drop

#從一個元素滑動到另一個元素,第二個元素替代第一個元素原本屏幕上的位置
#參數:
# origin_el:滑動開始的元素
# destination_el:滑動結束的元素
driver.drag_and_drou(origin_el,destination_el)示例
將“存儲”拖拽到“更多”
save_button = driver.findelement_by_xpath("//*[@text='存儲']")
morebutton=driver.findelementby-xpath("//*[@text='更多']")
driver.draganddrop(save_button,more_button)

滑動和拖拽事件的選擇

滑動和拖拽無非就是考慮是否有“慣性”,以及傳遞的參數是“元素”還是“坐標”。
可以分成以下四種情況
有“慣性”,傳入“元素” scroll
無“慣性”,傳入“元素” drag_and_drop
有“慣性”,傳入“坐標” swipe,并且設置較短的duration時間
無“慣性”,傳入“坐標” swipe,并且設置較長的duration時間

慣性大致可以理解為,我們使用手機 在看比較長的內容時。突然向上滑動一下屏幕,文字內容會突然向下翻閱,隨之會有“慣性的“慢慢停下來。

手機操作api(獲取手機分辨率、截圖、手機網絡、通知欄)

# 獲取手機分辨率print(driver.get_window_size())
print(driver.get_window_size()["height"])
print(driver.get_window_size()["width"])# 截圖
#參數:
# filename:存儲到指定路徑下,并指定格式的圖片
get_screenshot_as_file(filename)
示例
driver.get_screenshot_as_file(os.getcwd()+os.sep+'./screen.png')# 獲取手機網絡
# 應用切景
# 視頻應用在使用流量看視頻的時候,大部分都會提示用戶正在是否繼續播放。作為測試人員,我們可能需要用自動
# 化的形式來判斷是否有對應的提示。即,用流量的時候應該有提示,不用流量的時候應該沒有提示。
driver.network_connection
# 網絡結果對照如下圖

在這里插入圖片描述

# 設置當前網絡
driver.set_network_connection()# 輸入參數使用系統提供的類型
from appium.webdriver.connectiontype import ConnectionType

在這里插入圖片描述

# 操作通知欄
# 打開手機通知欄
driver.open_notifications()
# 注意點
# appium官方并沒有為我們提供關閉通知的api,那么現實生活中怎么關閉,就怎樣操作就行,比如,手指從下往上滑動,或者,按返回鍵

模擬按鍵

通過真實的按鍵或手機虛擬鍵盤進行輸入框或交互框的測試數據輸入。
這里區分為兩種鍵盤,一種是模擬手機的物理按鍵(菜單、Home、返回等),另一種是模擬鍵盤按鍵。
使用driver.press_keycode() 或者 driver.keyevent() 兩種函數。注意.press_keycode() 函數只適用于Android。
如果要使用對應的按鍵只需要在方法內填入相應的參數即可。

#只需要在相應方法內填入相應的參數即可。
#兩種方式均可
driver.keyevent(3)
driver.press_keycode(7)

按鍵對應參數值
在這里插入圖片描述
另外需要模擬長按某些物理按鍵的話(長按電源、長按音量),就可以使用long_press_keycode()函數來進行操作。

在這里插入圖片描述
在這里插入圖片描述

Appium結合PO設計模式、數據驅動、Pytest、jenkins(參考Web端的博客,或自行查閱資料)


參考目錄

https://www.bilibili.com/video/BV11p4y197HQ
https://www.bilibili.com/video/BV1Fj42197Bc
https://www.bilibili.com/video/BV1R3411f7nA
https://www.bilibili.com/video/BV14D421L7J4
https://www.bilibili.com/video/BV1Ef4y1P7zQ
https://blog.csdn.net/m0_50944918/article/details/112851529
https://www.byhy.net/auto/appium/01/
https://blog.csdn.net/YJT1002/article/details/140297245
https://austin.blog.csdn.net/article/details/126364649
https://austin.blog.csdn.net/article/details/126464298
https://austin.blog.csdn.net/article/details/126554755
https://austin.blog.csdn.net/article/details/126631919
https://blog.csdn.net/m0_74105684/article/details/136592906
https://blog.csdn.net/ZL_1618/article/details/132356781

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82864.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82864.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82864.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【論文解讀】DETR: 用Transformer實現真正的End2End目標檢測

1st authors: About me - Nicolas Carion?Francisco Massa? - ?Google Scholar? paper: [2005.12872] End-to-End Object Detection with Transformers ECCV 2020 code: facebookresearch/detr: End-to-End Object Detection with Transformers 1. 背景 目標檢測&#…

性能測試-jmeter實戰1

課程:B站大學 記錄軟件測試-性能測試學習歷程、掌握前端性能測試、后端性能測試、服務端性能測試的你才是一個專業的軟件測試工程師 性能測試-jmeter實戰1 為什么需要性能測試呢?性能測試的作用?性能測試體系性能測試基礎性能測試工具性能監控…

HTML、XML、JSON 是什么?有什么區別?又是做什么的?

在學習前端開發或者理解互聯網工作原理的過程中,我們經常會遇到三個非常重要的概念:HTML、XML 和 JSON。它們看起來有點像,但其實干的事情完全不同。 🏁 一、他們是誰?什么時候誕生的? 名稱全稱誕生時間誰…

HTML5 全面知識點總結

一、HTML 基礎概念 HTML:超文本標記語言,用于創建網頁和 Web 應用的結構。 超文本:可以包含文字、圖片、音頻、視頻、鏈接等多種媒體。 標記語言:通過標簽標記網頁的各個部分。 二、HTML5 的新特性(區別于 HTML4&am…

記錄一個難崩的bug

1.后端配置了 Filter 過濾器,如果再配置了Configuration ,那么會出現沖突嗎? 過濾器與Configuration類本身無直接沖突,但需注意注冊機制、執行順序和依賴管理。通過顯式控制過濾器的注冊方式和優先級,結合Spring Security的鏈式配…

RabbitMQ 與其他 MQ 的對比分析:Kafka/RocketMQ 選型指南(二)

四、三者性能大比拼 4.1 吞吐量 吞吐量是衡量消息隊列處理能力的重要指標,它反映了在單位時間內消息隊列能夠處理的消息數量。在這方面,Kafka 表現最為出色,其獨特的設計使其能夠輕松處理每秒數百萬條消息 。Kafka 采用分布式架構和分區機制…

【C】箭頭運算符

在C語言中,p_tone->power_off 是一種通過指針訪問結構體成員的方法,稱為箭頭運算符(->)。它主要用于以下場景: 1. 語法解釋 p_tone:是一個指向結構體(或聯合體)的指針。powe…

【Unity】 HTFramework框架(六十六)缺省的運行時組件檢視器

更新日期:2025年5月29日。 Github 倉庫:https://github.com/SaiTingHu/HTFramework Gitee 倉庫:https://gitee.com/SaiTingHu/HTFramework 索引 一、缺省的運行時組件檢視器1.自定義運行時組件檢視器 二、使用缺省的運行時組件檢視器1.定義組…

AI和大數據:是工具,還是操控人心的“隱形之手”?

AI和大數據:是工具,還是操控人心的“隱形之手”? 開場白:聊點現實的 在這個數據至上的時代,我們的生活被AI和大數據悄然改變。從電商推薦、短視頻算法,到招聘篩選、智慧城市,它們像一個貼心的…

k8s部署ELK補充篇:kubernetes-event-exporter收集Kubernetes集群中的事件

k8s部署ELK補充篇:kubernetes-event-exporter收集Kubernetes集群中的事件 文章目錄 k8s部署ELK補充篇:kubernetes-event-exporter收集Kubernetes集群中的事件一、kubernetes-event-exporter簡介二、kubernetes-event-exporter實戰部署1. 創建Namespace&a…

Apache 高級配置實戰:從連接保持到日志分析的完整指南

Apache 高級配置實戰:從連接保持到日志分析的完整指南 前言 最近在深入學習 Apache 服務器配置時,發現很多朋友對 Apache 的高級功能還不夠了解。作為一個在運維路上摸爬滾打的技術人,我想把這些實用的配置技巧分享給大家。今天這篇文章會帶…

【Stable Diffusion 1.5 】在 Unet 中每個 Cross Attention 塊中的張量變化過程

系列文章目錄 文章目錄 系列文章目錄前言特征圖和注意力圖的尺寸差異原因在Break-a-Scene中的具體實現總結 前言 特征圖 (Latent) 尺寸和注意力圖(attention map)尺寸在擴散模型中有差異,是由于模型架構和注意力機制的特性決定的。 特征圖和注意力圖的尺寸差異原…

【監控】Prometheus+Grafana 構建可視化監控

在云原生和微服務架構盛行的今天,監控系統已成為保障業務穩定性的核心基礎設施。作為監控領域的標桿工具,Prometheus和Grafana憑借其高效的數據采集、靈活的可視化能力,成為運維和開發團隊的“標配”。 一、Prometheus Prometheus誕生于2012…

替代 WPS 的新思路?快速將 Word 轉為圖片 PDF

在這個數字化辦公日益普及的時代,越來越多的人開始關注文檔處理工具的功能與體驗。當我們習慣了某些便捷操作時,卻發現一些常用功能正逐漸變為付費項目——比如 WPS 中的一項實用功能也開始收費了。 這款工具最特別的地方在于,可以直接把 W…

CodeTop之數組中的第K個最大的元素

題目鏈接 215. 數組中的第K個最大元素 - 力扣(LeetCode) 題目解析 算法原理 解法一: 直接理由java內部的排序函數,Arrays.sort()進行排序, 然后我們直接返回第k個最大的元素 nums[nums.length-k] 解法二: 使用堆 我們先把所有元素丟到大根堆里面…

AI任務相關解決方案1-基于NLP的3種模型實現實體識別,以及對比分析(包括基于規則的方法、CRF模型和BERT微調模型)

大家好,我是微學AI,今天給大家介紹一下AI任務相關解決方案1-基于NLP的3種模型實現實體識別,以及對比分析。本文將深入探討三種不同的命名實體識別(NER)方法,包括基于規則的方法、CRF模型和BERT微調模型,用于識別文本中的地名(LOC)、機構名稱(ORG)和人名(PER)實體。通過系統…

IP動態偽裝開關

IP動態偽裝開關 在OpenWrt系統中,IP動態偽裝(IP Masquerading)是一種網絡地址轉換(NAT)技術,用于在私有網絡和公共網絡之間轉換IP地址。它通常用于允許多個設備共享單個公共IP地址訪問互聯網。以下是關于O…

【MySQL】第10節|MySQL全局優化與Mysql 8.0新增特性詳解

全局優化 mysql server參數 1. max_connections(最大連接數) 含義:MySQL 服務允許的最大并發連接數(包括正在使用和空閑的連接)。超過此限制時,新連接會被拒絕(報錯 Too many connections&am…

VS Code 插件 Git History Diff

插件名 進命令行,進Git自己那個分支 查看分支 提交到Git的后想再把另一個也提交到那個分支,用這個命令

Shell腳本中的常用命令

一.設置主機名稱 文件設置 文件開機時已讀取所以要重新進入 命令更改(即使生效) 二.網絡管理命令 1.查看網卡命令 設置網卡 1)DHCP工作模式 2)靜態IP 3)修改網卡信息 三.簡單處理字符 1.打印連續數字 連續打印3個數字 指定打…