一、什么是自動(dòng)化測(cè)試,了解自動(dòng)化測(cè)試
所謂的自動(dòng)化測(cè)試就是前期通過(guò)人肉編碼,完成測(cè)試框架,后期解放雙手自動(dòng)完成規(guī)定的測(cè)試流程。
自動(dòng)化測(cè)試主要分為三層:UI層、接口層、單元層。
移動(dòng)端、web端通常所說(shuō)的自動(dòng)化測(cè)試是指UI層測(cè)試,基本原理就是:基于頁(yè)面元素的識(shí)別和定位來(lái)模擬用戶行為,首先識(shí)別到某個(gè)元素,比如一個(gè)按鈕,然后定義一個(gè)動(dòng)作,比如點(diǎn)擊,這樣就通過(guò)代碼模擬完成了一次按鈕的點(diǎn)擊,代替了人工去點(diǎn)擊。如果后期再加入數(shù)據(jù)驅(qū)動(dòng)和Page Object思想就基本可以形成一個(gè)UI層自動(dòng)化測(cè)試框架了。
目前我覺(jué)得UI層測(cè)試有以下幾點(diǎn)問(wèn)題:
版本迭代UI變化太快,導(dǎo)致腳本也需要不斷的更新,目前在泰然金融項(xiàng)目中,只針對(duì)主流程編寫(xiě)了測(cè)試腳本,UI變化帶來(lái)的問(wèn)題暫未體現(xiàn)。
見(jiàn)效慢,初期還是有一定的學(xué)習(xí)成本,包括搭建環(huán)境,編寫(xiě)腳本,熟悉測(cè)試框架以及設(shè)計(jì)模式。但是我相信后期自動(dòng)化測(cè)試帶來(lái)的效果也是非??捎^的。
APP端、web端編碼可能不夠規(guī)范,導(dǎo)致很多元素定位和識(shí)別非常困難。
總的來(lái)說(shuō)UI自動(dòng)化測(cè)試可能更適合于主流程的測(cè)試,就是一些非常重要并且不會(huì)頻繁變化的流程,對(duì)主流程做自動(dòng)化回歸測(cè)試,可以有效避免線上重要功能出現(xiàn)bug。
常見(jiàn)自動(dòng)化測(cè)試方案介紹:
iOS:
iOS測(cè)試分為UI和Unit測(cè)試,Unit測(cè)試一般就是用代碼檢測(cè)代碼,因此Unit測(cè)試比較適用于一些復(fù)雜代碼的檢查驗(yàn)證,以及一些暴露在.h中的方法;UI測(cè)試就是上文所描述的。
iOS UI測(cè)試的一些常見(jiàn)方案:
? ? ? KIF 全稱是Keep it functional。它是一個(gè)建立在XCTest的UI測(cè)試框架,通過(guò)accessibility來(lái)定位具體的控件(所以在編碼的時(shí)候一定要設(shè)置AccessibilityLabel和AccessibilityTrait),再利用私有的API來(lái)操作UI。由于是建立在XCTest上的,所以你可以完美的借助Xcode的測(cè)試相關(guān)工具(包括命令行腳本),去模擬用戶輸入來(lái)測(cè)試。同時(shí)也支持UIWebView的測(cè)試。
? ? ? Frank 使用Ruby語(yǔ)言,開(kāi)源內(nèi)嵌Server型,通過(guò)注入Server到APP使用API,通過(guò)Server對(duì)外通信完成UI操作。支持CI持續(xù)集成,不支持UIWebView,要求測(cè)試時(shí)在應(yīng)用程序內(nèi)部編譯。
? ? ? Appium 一個(gè)開(kāi)源的、跨平臺(tái)的自動(dòng)化測(cè)試工具,支持IOS、Android和FirefoxOS平臺(tái)。
? ? ? EarlGrey Google推出的iOS功能性UI測(cè)試框架,其所提供的主要特性:強(qiáng)大的內(nèi)建同步機(jī)制,測(cè)試會(huì)在與UI進(jìn)行交互前自動(dòng)等待動(dòng)畫(huà)、網(wǎng)絡(luò)請(qǐng)求等事件。
Android:
Android平臺(tái)的自動(dòng)化測(cè)試一般分為2個(gè)方向:
Android端的自動(dòng)化測(cè)試框架
Espresso 是 Google 針對(duì) Android 平臺(tái)開(kāi)源的一款 Android 自動(dòng)化測(cè)試框架,主要是用于 Android App UI 自動(dòng)化測(cè)試。
UI Automator
Appium
Monkey
MonkeyRunner
Robotium
Ronaorex
TestBird
(若有興趣,請(qǐng)自行搜相關(guān)文檔了解)
? ? 各大云測(cè)試平臺(tái)(騰訊優(yōu)測(cè)云測(cè)、HUAWEI開(kāi)發(fā)者聯(lián)盟、貫眾云測(cè)試、Testin云測(cè))
二、Appium
為什么選擇Appium
Appium是一個(gè)開(kāi)源、跨平臺(tái)的自動(dòng)化測(cè)試工具,同時(shí)支持iOS、Android、H5,接口基本一致,減少開(kāi)發(fā)維護(hù)成本;
可以使用多種語(yǔ)言編寫(xiě)測(cè)試腳本(如:Ruby、C#、Java、JavaScript、OC、PHP、Python等語(yǔ)言);
不需要重新編譯應(yīng)用就可以進(jìn)行測(cè)試;
不依賴項(xiàng)目源代碼;
社區(qū)活躍,文檔健全;
Appium采用Client-Server的架構(gòu)設(shè)計(jì),并采用標(biāo)準(zhǔn)的HTTP通信協(xié)議;Server端負(fù)責(zé)與iOS、Android原生測(cè)試框架交互,無(wú)需測(cè)試人員關(guān)注細(xì)節(jié)實(shí)現(xiàn);
Client端基本上可以采用任意主流編程語(yǔ)言編寫(xiě)測(cè)試用例,減少了學(xué)習(xí)成本;
Appium相關(guān)概念
Client/Server Architecture:Appium是用Node.js編寫(xiě)的服務(wù)器,可以使用npm安裝,也可以直接安裝GUI工具(Appium Desktop)。Server的功能其實(shí)就是:監(jiān)聽(tīng)一個(gè)端口,然后由Client端發(fā)來(lái)指令,將這些指令轉(zhuǎn)成移動(dòng)設(shè)備或者瀏覽器可以理解的的形式,然后由設(shè)備執(zhí)行這些指令,最后把執(zhí)行結(jié)果返回給Appium Server,并在Client端展示結(jié)果。Client是發(fā)起指令的設(shè)備,一般就是指測(cè)試腳本的運(yùn)行環(huán)境,也就是代碼,只要實(shí)現(xiàn)了WebDriver標(biāo)準(zhǔn)協(xié)議就可以,可以是Java、Ruby、Python、JS、OC等語(yǔ)言編寫(xiě)的代碼。
Session:自動(dòng)化始終圍繞一個(gè)Session進(jìn)行,客戶端初始化一個(gè)session來(lái)與服務(wù)端交互,不同的語(yǔ)言最終都是給服務(wù)端發(fā)送一個(gè)JSON對(duì)象,也就是Desired Capabilities,然后服務(wù)端就會(huì)開(kāi)啟一個(gè)自動(dòng)化的session,并返回一個(gè)session id,后續(xù)所有的請(qǐng)求都會(huì)帶上使用這個(gè)session id。
Desired Capabilities:以key-value的形式,將配置信息轉(zhuǎn)換成json對(duì)象傳輸給服務(wù)端,還有一個(gè)重要的作用就是告訴Server本次測(cè)試的設(shè)備環(huán)境,比如iOS、Android還是瀏覽器。
Appium-Server:通過(guò)npm install -g appium安裝了appium之后,在命令行輸入appium,就是啟動(dòng)了appium server
Appium-Client:appium客戶端有很多語(yǔ)言庫(kù),Java、Ruby、Python、PHP、JS、C#、OC...這些庫(kù)都實(shí)現(xiàn)了Appium對(duì)WebDriver協(xié)議的擴(kuò)展,加入了一些方便的方法,比如swipe之類,Appium Client讓我們可以更方便的寫(xiě)出可讀性更好的測(cè)試用例。
Appium.app/.exe:分別是Mac、Windows系統(tǒng)下的可視化工具,可以直接查看頁(yè)面的UI結(jié)構(gòu),還可以錄制用戶行為生成相應(yīng)的測(cè)試腳本代碼,對(duì)于元素定位有很大的幫助。
Appium Inspector:用例查看APP的元素結(jié)構(gòu)與基本信息,還可以與元素交互,在Appium GUI工具中可以直接使用,如下圖。
WebDriverAgent:Facebook推出的一款iOS移動(dòng)測(cè)試框架,在iOS端實(shí)現(xiàn)了一個(gè)WebDriver Server,借助這個(gè)Server可以遠(yuǎn)程控制iOS設(shè)備,可以啟動(dòng)、關(guān)閉應(yīng)用,點(diǎn)擊、滾動(dòng)視圖,或者確定頁(yè)面展示是否正確。支持iOS模擬器和真機(jī)。
Appium工作原理
以Mac系統(tǒng)為例,使用Java(java-client)編寫(xiě)Appium自動(dòng)化測(cè)試腳本并執(zhí)行,首先會(huì)請(qǐng)求Appium-Server,然后Server經(jīng)過(guò)解析,驅(qū)動(dòng)iOS/Android模擬器或者設(shè)備來(lái)執(zhí)行Appium自動(dòng)化腳本,Windows平臺(tái)原理類似。
Appium環(huán)境搭建
目前我們是搭建了一套Appium+Java+Windows/Mac+Android Studio環(huán)境(Mac環(huán)境搭建步驟),IDE使用Android Studio,也可以用IntelliJ IDEA、Eclipse,使用Java編寫(xiě)測(cè)試腳本。
(Windows系統(tǒng)教程:https://www.testwo.com/blog/8000)
(Mac系統(tǒng)教程:https://juejin.im/post/5b2f291ce51d4558d217d5f6)
三、編寫(xiě)自動(dòng)化測(cè)試腳本
元素定位
appium一些常見(jiàn)的定位方式(復(fù)雜元素可以配合Inspector查找):
cssSelector # Selenium 最強(qiáng)大的定位方法,比 xpath 速度快,但比 xpath 難上手
linkText # 鏈接元素的全部顯示文字
partialLinkText # 鏈接元素的部分顯示文字
name # 元素的 name 屬性,目前官方在移動(dòng)端去掉這個(gè)定位方式,使用 AccessibilityId 替代
tagName # 元素的標(biāo)簽名
className # 元素的?class?屬性
id # 元素的 id 屬性
xpath # 比 css 定位方式稍弱一些的定位方法,但勝在容易上手,比較好使用,缺點(diǎn)就是速度慢一些。
AccessibilityId # Appium 中用于替代 name 定位方式
AndroidUIAutomator # Android 測(cè)試,最強(qiáng)大速度最快的定位方式
iOSNsPredicateString # iOS 謂詞的定位方式,僅支持 XCTest 框架,需大于 iOS?9.3或以上
IosUIAutomation # iOS 謂詞的定位方式,僅支持 UIAutomation 框架,需大于 iOS?9.3或以下
iOSClassChain # 國(guó)外大神 Mykola Mokhnach 開(kāi)發(fā)類似 xpath 的定位方式,僅支持 XCTest 框架,,不如 xpath 和 iOSNsPredicateString 好
windowsAutomation # windows 應(yīng)用自動(dòng)化的定位方式
className
使用元素的className屬性定位,適用于iOS、Android
driver.findElementByClassName("XCUIElementTypeButton");
id
使用元素的resource-id屬性定位,適用于Android4.2以上版本,定位簡(jiǎn)潔有效,推薦使用。
driver.findElementById("toolbar_back_btn");
xpath
iOS、Android都支持,定位速度非常慢,除非萬(wàn)不得已不要使用,官方也不推薦使用,但是appium框架還是支持xpath的,畢竟很多元素只能使用xpath定位。
比如金融登錄頁(yè)面,手機(jī)號(hào)輸入框,使用xpath定位,尋找元素,并且輸入手機(jī)號(hào)這個(gè)流程大概需要24秒;使用className執(zhí)行這個(gè)流程只需要7秒左右。
driver.findElementByXPath("(//XCUIElementTypeOther[@name=\"確認(rèn)無(wú)誤\"])[2]");
xpath定位分為4種:
1.使用絕對(duì)路徑定位(不推薦):
driver.findElementByXPath("className/className/className....")
2.使用相對(duì)路徑定位:
driver.findElementByXPath("http://className")
3.使用元素索引定位:
driver.findElementByXPath("http://className[index]")
4.使用元素屬性定位:
driver.findElementByXPath("http://className[@label="確定"][@enable=true]")
AccessibilityId
替代name屬性的定位方式,在iOS上主要是元素的label和name屬性,在Android上是content-desc屬性,如果label/name/content-desc為空,則不能使用AccessbilityId定位元素
driver.findElementByAccessibilityId("獲取驗(yàn)證碼");
AndroidUIAutomator
僅支持Android4.2以上系統(tǒng),可使用元素的單個(gè)或者多個(gè)屬性定位,支持以下屬性定位:
index(int?index)?
text(String text)?
resourceId(String id)?
className(String className)?
packageName(String packageName)?
description(String desc)?
checked(boolean?val)?
clickable(boolean?val)?
enabled(boolean?val)?
longClickable(boolean?val)?
password(boolean?val)?
selected(boolean?val)?
instance(int?val)
# 其他一些詳細(xì)方法(包括正則表達(dá)式匹配),請(qǐng)查看 Android 源碼中,UiSelector 類定義的方法
例子:
MobileBy.AndroidUIAutomator("new UiSelector().text(\"確定\").clickable(true)")
iOSNSPredicate
僅支持iOS,可使用元素的單個(gè)或者多個(gè)屬性定位,詳細(xì)請(qǐng)參考iOSNSPredicate定位
手勢(shì)操作
Appium提供了點(diǎn)擊tap()、滑動(dòng)swipe()、縮小pinch()、放大zoom()、移動(dòng)move()等手勢(shì)操作API。
設(shè)計(jì)模式
Appium通常使用Page Object設(shè)計(jì)模式,將每一個(gè)測(cè)試頁(yè)面抽象為1個(gè)Page類,并在該類中封裝了本頁(yè)面的測(cè)試對(duì)象和基本的測(cè)試步驟,以提高代碼的可讀性復(fù)用性通用性和一致性。使用Page Object模式的項(xiàng)目結(jié)構(gòu)如下圖所示:
