
本文為霍格沃茲測試學院學員學習筆記。
對測試人來說,Appium 是非常重要的一個開源跨平台自動化測試工具,它允許測試人員在不同的平台(iOS、Android 等)使用同一套 API 來寫自動化測試腳本,這樣可大幅提升代碼復用率和工作效率。
本文匯總了從 Appium 基礎到自動化測試高級實戰中,所涉及到的方方面面的知識點精華內容(如下所示),希望對大家快速總結和復習有所幫助。
Appium 從基礎到自動化測試框架實戰
- Appium 基礎 1(環境搭建和簡介)
- Appium 基礎 2(元素定位和元素常用方法)
- Appium 基礎 3(手勢操作和 uiautomator 查找元素)
- Appium 基礎 4(顯式等待)
- Appium 基礎 5(toast 和參數化)
- Appium 基礎 6(webview)
- Appium_ 企業微信練習 (非 PO,增加和刪除聯系人)
- Appium_ 企業微信練習 (PO--增加聯系人)
Appium 環境搭建
JDK 的搭建
- 下載 1.8 的 jdk
- 新建環境變量:JAVA_HOME 值為:D:\Program Files\Java\jdk1.7.0
- 新建環境變量:CLASSPATH 值為:.;%JAVA_HOME%\lib;(注意:點號表示當前目錄,不能省略)
- 在系統變量 Path 的值的前面加入以下內容:%JAVA_HOME%\bin
SDK 的配置
- 下載 sdk
- 打開 sdk 的 sdk manager,安裝 tools 前 3 個東西和 google 的 usb 驅動
- 配置 Android home 里面的 platform-tools 和 tools
Appium 的搭建
- 安裝 node.js,配置 node.js 的環境變量
- npm install -g cnpm --registry=https://registry.npm.taobao.org
- cnpm install -g appium
- cnpm install -g appium-doctor
- pip install appium-python-client
appium 運行的 python 代碼
- mumu 連接 adb 是:adb connect 127.0.0.1:7555
from appium import webdriver
#設置 caps 的值
desire_cap= {
#默認是 Android
"platformName":"android",
#adb devices 的 sn 名稱
"deviceName":"127.0.0.1:7555",
#包名
"appPackage":"com.xueqiu.android",
#activity 名字
"appActivity":".view.WelcomeActivityAlias"
}
#運行 appium,前提是要打開 appium server
driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",desire_cap)
Appium 的簡介
Appium 的引擎
- Android 是 uiautomator2
- ios 是 xcuitest
Appium 的設計理念
- webdriver 是基於 http 協議的,第一連接會建立一個 session 會話,並通過 post 發送一個 json 告知服務端相關測試信息
- client/server 設計模式
- 客戶端通過 webdriver json wire 協議與服務器通訊
- 多語言支持
- server 可以放在任何地方
- 服務器 nodejs 開發的 http 服務
- appium 使用 appium-xcuitest-driver 來測試 iphone 設備,其中需要安裝 Facebook 出的 WDA(webdriver agent) 來驅動 ios 測試
Appium 的生態工具
- adb:Android 控制工具
- appium Destkop:內嵌 appium server 和 inspector 的綜合工具
- appium server:appium 的核心工具,命令行工具
- appium client:各種語言的客戶端封裝庫,用戶連接 appium server,包含 python、java、ruby 等
- appcrawler 自動遍歷工具
獲取 App 的信息
- 獲取當前元素界面:adb shell dumpsys activity top
- 獲取任務列表:adb shell dumpsys activity activities
- 獲取 app 的 package 和 activity:adb shell;然后 logcat | grep -i displayed
- 啟動應用:adb shell am start -W -n "com.xueqiu.android/.view.WelcomeActivityAlias -S
Capability 設置
- 文檔地址:http://appium.io/docs/en/writing-running-appium/caps/index.html
- platformName:android 通常都是寫 android
- deviceName:127.0.0.1:7555 這個通常是 adb devices 的名稱
- appPackage:com.xueqiu.android 這個是 app 的 package 包名
- appActivity:.view.WelcomeActivityAlias 這個是 app 的 activity 名
- noReset:true, false 是否重置測試的環境(例如首次打開彈框,或者登陸信息)
- unicodeKeyboard:true, false 是否需要輸入非英文之外的語言並在測試完成后重置輸入法,比如輸入中文
- dontStopAppOnReset:true, false 首次啟動的時候,不停止 app
- skipDeviceInitialization:true, false 跳過安裝,權限設置等操作
測試用的 apk
- https://github.com/appium/appium/tree/master/sample-code/apps
Android 的基礎知識
Android 的布局
- Android 是通過容器的布局屬性來管理子控件的位置關系,布局過程就是把界面上的所有的控件,根據他們的間距的大小,擺放在正確的位置
- 線性布局:LinearLayout
- 相對布局:RelativeLayout
- 幀布局:FrameLayout
- 絕對布局:AbsoluteLayout
- 表格布局:TableLayout
- 網格布局:GirdLayout
- 約束布局:ConstraintLayout
Android 四大組件
- activity:與用戶交互的可視化界面
- service:實現程序后台運行的解決方案,比如 qq 音樂的音樂在后台運行,沒有界面
- content provide:內容提供者,提供程序所需要的數據,比如?提供數據庫?
- broadcast receiver:廣播接收器,監聽外部事件的到來(比如來電)
Android 常用的控件
- TextView:文本控件
- EditText:可編輯文本控件
- Button:按鈕
- ImageButton:圖標按鈕
- ToggleButton:開關按鈕
- ImageView:圖片控件
- CheckBox:復選框控件
- RadioButton:單選框控件
控件知識
- dom:Document Object Model 文檔對象模型
- dom 應用:最早應用於 html 和 js 的交互,用戶表示界的控件層級,界面的結構化描述,常見的格式為 html、xml。核心元素為節點和屬性
- xpath:xml 路徑語言,用於 xml 中的節點定位
- Android 的應用層級結構是定制的 xml
- app source 類似於 dom,表示 app 的層級,表示界面里面所有的控件數的結構
- 每個控件都有它的屬性(resourceid、xpath、aid),沒有 css 屬性
Appium 的元素定位
普通方式的定位
- driver.find_element_by_accessibility_id() 對應 content-desc
- driver.find_element_by_id() 對應 resource-id
- driver.find_element_by_name() 對應 text
- driver.find_element_by_xpath() 對應 xpath
By 的定位方式
- 首先要 from appium.webdriver.common.mobileby import MobileBy as By
- self.driver.find_element(By.ID,"") 對應 resource-id
- self.driver.find_element(By.XPATH,"") 對應 xpath
- self.driver.find_element(By.ACCESSIBILITY_ID,"") 對應 content-desc
- self.driver.find_element(By.NAME,"") 對應 text
Xpath 的定位方式
- driver.find_element_by_xpath("//*[@text=' 掃一掃 ']")
- driver.find_element_by_xpath("//*[@resource-id='com.taobao.taobao:id/tv_scan_text']")
- driver.find_element_by_xpath("//*[@content-desc=' 幫助 ']")
- driver.find_element(By.XPATH,"//*[@resource-id='com.xueqiu.android:id/name' and @text=' 阿里巴巴 ']") and 的使用
- 父類和兄弟類的方法://[@text=' 性別 ']/..//[@text=' 男 ']。其中 /.. 表示父類,//* 就是兄弟,孫子等類
- //*[Contains(@text,"tong")] 這是 xpath 的 text 模糊搜索的方法
元素的方法
元素的常用方法
- 點擊方法:element.click()
- 輸入操作:element.send_keys("tong")
- 設置元素的值:element.set_value("tongtong")
- 清除操作:element.clear()
- 是否可見:element.is_displayed 返回 true or false
- 是否可用:element.enabled() 返回 true or false
- 是否被選中:element.is_selected() 返回 true or false
- 獲取屬性值:element.get_attribute(name)
屬性值介紹
- get_attribute(name) 獲取的屬性名稱和 uiautomatorviewer 的一致,但是 index 的值獲取不了
- 真假獲取的值是 true 和 false 的字符串,並不是 python 的 boolean 值
元素常用的屬性
- 獲取元素文本:element.text
- 獲取元素坐標:element.location
- 結果:{'y':19,'x':498}
- 獲取元素尺寸(高和寬):element.size
- 結果:{'width':500,'height':22}
實戰小案例 1
- 打開雪球 app
- 點擊搜索輸入框
- 向搜索輸入框輸入 “阿里巴巴”
- 在搜索的結果里選擇阿里巴巴,然后點擊
- 獲取這只上香港 阿里巴巴的股價,並判斷這只股價的價格>200
代碼
from time import sleep
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy as By
class TestFind():
#設置 caps 的值
def setup(self):
self.desire_cap= {
#默認是 Android
"platformName":"android",
#adb devices 的 sn 名稱
"deviceName":"127.0.0.1:7555",
#包名
"appPackage":"com.xueqiu.android",
#activity 名字
"appActivity":".view.WelcomeActivityAlias",
"noReset":"true",
"unicodeKeyboard":True
}
#運行 appium,前提是要打開 appium server
self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
self.driver.implicitly_wait(5)
def test_search(self):
"""
1. 打開雪球 app
2. 點擊搜索輸入框
3. 向搜索輸入框輸入 “阿里巴巴”
4. 在搜索的結果里選擇阿里巴巴,然后點擊
5. 獲取這只上香港 阿里巴巴的股價,並判斷這只股價的價格>200
:return:
"""
sleep(3)
#點擊搜索框
self.driver.find_element(By.ID,"com.xueqiu.android:id/tv_search").click()
#向搜索框輸入阿里巴巴
self.driver.find_element(By.ID,"com.xueqiu.android:id/search_input_text").send_keys(" 阿里巴巴 ")
#找到搜索框預覽結果的阿里巴巴,並點擊
self.driver.find_element(By.XPATH,"//*[@resource-id='com.xueqiu.android:id/name' and @text=' 阿里巴巴 ']").click()
#選擇 HK 股價的元素
prices=self.driver.find_elements(By.ID,"com.xueqiu.android:id/current_price")[1]
#提取股價的 text 屬性
price=float(prices.text)
#判斷股價是否大於 200
assert price > 200
實戰小案例 2
- 打開雪球首頁
- 定位首頁的搜索框
- 判斷搜索框是否可用,並查看搜索框 name 屬性值
- 打印搜索框這個元素的左上角坐標和它的寬高
- 向搜索框輸入:alibaba
- 判斷阿里巴巴是否可見
- 如果可見,打印搜索成功點擊,如果不可見,打印搜索失敗
代碼
from time import sleep
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy as By
class TestFind():
#設置 caps 的值
def setup(self):
self.desire_cap= {
#默認是 Android
"platformName":"android",
#adb devices 的 sn 名稱
"deviceName":"127.0.0.1:7555",
#包名
"appPackage":"com.xueqiu.android",
#activity 名字
"appActivity":".view.WelcomeActivityAlias",
"noReset":"true",
"unicodeKeyboard":True
}
#運行 appium,前提是要打開 appium server
self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
self.driver.implicitly_wait(5)
def test_element_function(self):
"""
1. 打開雪球首頁
2. 定位首頁的搜索框
3. 判斷搜索框是否可用,並查看搜索框 name 屬性值
4. 打印搜索框這個元素的左上角坐標和它的寬高
5. 向搜索框輸入:alibaba
6. 判斷阿里巴巴是否可見
7. 如果可見,打印搜索成功點擊,如果不可見,打印搜索失敗
:return:
"""
sleep(8)
#找到搜索框的元素
search=self.driver.find_element(By.ID, "com.xueqiu.android:id/tv_search")
#當搜索框是可用(類似可點擊)后才進行下面的操作,is_enabled() 返回 Ture or False
if search.is_enabled():
#打印搜索框的 text 值
print(search.text)
#打印搜索框左上角的坐標
print(search.location)
#打印搜索框的高和寬
print(search.size)
#點擊搜索框,才可以進行下面的操作
search.click()
#在搜索框中輸入阿里巴巴
self.driver.find_element(By.ID, "com.xueqiu.android:id/search_input_text").send_keys(" 阿里巴巴 ")
#定義找到預覽結果的阿里巴巴的元素
alibaba=self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name' and @text=' 阿里巴巴 ']")
#當 alibaba 元素可見,打開搜索成功,否則打印搜索失敗
if alibaba.is_displayed():
print(" 搜索成功 ")
else:
print(" 搜索失敗 ")
更多內容,我們在后續文章分享。
想觀看更多內容,可關注公眾號:霍格沃茲測試學院