《移动App测试实战》——2.2 App UI层面的自动化
本節書摘來自華章出版社《移動App測試實戰》一 書中的第2章,第2.2節,作者:邱鵬 陳吉 潘曉明,更多章節內容可以訪問云棲社區“華章計算機”公眾號查看。
2.2 App UI層面的自動化
除了上面介紹的基于接口的自動化,App UI層面的自動化也是一個重要的自動化技術。可以幫助快速地進行App功能的回歸。考慮到功能的變動和維護的代價,實際中投入產出比較高的方式是針對相對穩定的功能進行快速的回歸。也可以和后面討論的持續集成結合,做新構建的驗證。除了功能的自動化驗證之外,UI自動化技術還有一些其他的價值,比如第4章專項測試中介紹了使用UI自動化技術和云測試平臺來構造一套高效的兼容性測試方案,以及基于模糊測試思路和UI自動化建立的App穩定性測試平臺。這些都是以App UI自動化技術為前提的。
另外,需要指出的是,對于UI自動化應該有一個合理的期望。很多剛接觸App測試的人或者不了解App UI自動化的管理人員,可能提起App的測試技術,覺得最主要的就是App的自動化,而主要討論的就是UI的自動化技術。其實在經歷過一些大的項目之后,觀念可能會有些不同。基于目前多個團隊的實踐來看,如果對于一個在快速發展中的App,UI自動化可能更適合一些基礎功能的回歸,而不是替代手工的功能測試,特別是對于新的功能點。
接下來討論如何進行App UI的自動化測試,包括Android和iOS的做法。
2.2.1 Android的UI自動化技術
本節介紹Android UI自動化測試的一些基本的實現方式。由于各個項目的產品特性不同,這里不涉及UI自動化框架的封裝。
2.2.1.1 UI Automator Viewer
在進行Android UI自動化測試之前,作為測試人員,應當了解待測App的UI,包括使用了哪些控件、控件的類名、控件的id,等等。獲知這些信息之后才能寫測試腳本進行自動化測試。
Android SDK提供了一個UI Automator Viewer工具來幫助我們獲取這些信息。(需要安裝Android SDK Tools、Revision 21或以上,Android SDK Platform、API 16或以上)這個工具提供了一個可視化界面展示當前設備上的各個控件的屬性。按照下列步驟使用這個工具:
鏈接Android設備到計算機。
打開/tools/。
運行命令:uiautomatorviewer
點擊“Device Screenshot”按鈕,鼠標懸停到某一UI元素上面即可查看對應控件的詳細屬性,如圖2-16所示。
注意,如果你在計算機上連接了多個設備,在運行UI Automator Viewer前需要通過設置環境變量指定需要查看的UI設備。具體方法如下:
通過命令 adb devices找出設備序列號。
設置環境變量。
Windows
set ANDROID_SERIAL=<上一步獲取的設備序列號>
Linux
export ANDROID_SERIAL=<上一步獲取的設備序列號>
此外,UI Automator Viewer還提供了一個功能,可以查看UIAutomator測試框架可能不支持的控件。只需要在界面上點擊“Toggle NAF Nodes”按鈕(右上方感嘆號標記的按鈕)即可查看。如果在使用UIAutomator過程中發現某個控件不能被自動化驅動,可以對照UI Automator Viewer工具的結果排查問題。
在熟悉了待測App的UI以后,我們需要選擇一項或者多項測試方法來進行UI自動化測試。Android的UI自動化測試方法從技術角度來說,大致可以分為以下幾種:
public class MyTest extends ActivityInstrumentationTestCase2 {
SettingsActivity mMyActivity;
protected void setUp() throws Exception {
}
protected void tearDown() throws Exception { super.tearDown();}
public MyTest() {
}
public void testCase1()
{
ActionBar mMyBar= mMyActivity.getActionBar();
String title= mMyBar.getTitle().toString();
assertEquals(title,"My Application");
}
}`
我們的測試類需要繼承ActivityInstrumentationTestCase2,T為待測試的Activity類型。有兩個方法值得關注,一個是setUp方法。這個方法在測試開始的時候會被調用一次。我們可以在這個方法中進行初始化操作。上述代碼在這個方法中獲取了當前Activity對象的引用。另外一個方法是tearDown方法。這個方法在測試結束的時候會被調用一次。如有需要,我們可以在這個方法中添加代碼。
跟之前的JUnit測試類一樣,我們的測試方法需要以test開頭。在測試方法testCase1中,我們獲取頁面頭部的文字描述,進行了校驗。當頁面標題不是“My Application”的時候,此測試失敗。
上面的代碼只是一個簡單的例子,我們可以做更多的事情,例如使用Activity類的findViewById方法獲取需要的控件并做一些操作,如按鈕點擊,給輸入框添加輸入等。在此不一一贅述。
UIAutomator是谷歌新推出的UI自動化測試框架,需要API level 16和以上的操作系統才能使用。使用它能夠測試跨App交互的場景,但是它也有缺點。除了兼容性外,對一些控件也很難定位到。其中最大的缺點是不支持WebView的自動化測試。如果你的App中大量使用了WebView,并且需要對其進行UI自動化測試,那么你可能不得不選擇Instrumentation。
下面以Android Studio 1.0為例說明如何進行UIAutomator自動化測試:
1)在platformsandroid-XX下面找到uiautomator.jar。
2)將uiautomator.jar復制到項目的app/libs目錄下。
3)測試項目Module的依賴項增加libs下的所有jar:
public class MyTest extends UiAutomatorTestCase {
String packageName="com.example.test.myapplication"; String activityName="SettingsActivity"; protected void setUp() throws Exception {getUiDevice().pressHome();Runtime.getRuntime().exec("am start -a android.intent.action.MAIN -n "+packageName+"/."+activityName);UiObject mainUi=new UiObject(new UiSelector().packageName(packageName));assertTrue("App not started",mainUi.waitForExists(3000));super.setUp();}
protected void tearDown() throws Exception
{
super.tearDown();
}
}
}`
與Instrumentation類似,我們可以在setUp中寫初始化的代碼,在tearDown中寫清理工作的代碼。這里我們在setUp中進行了回到主界面的操作。以此作為測試的起點。這也是通常的做法。
另外,在初始化代碼中,我們調用了am命令啟動我們需要測試的App的Activity。這個放在初始化的目的通常是為了節省測試的時間。一些情況下,啟動Activity的工作只需要一次,我們可以寫很多個測試方法來測試這個啟動后的Activity的不同測試點。
在測試方法testCase1中,我們執行了如下的操作:
尋找第二個勾選框并點擊。
判斷Ringtone文本是否為不可用狀態(外觀變為灰色)。
這里有一些技巧。例如getUiDevice().waitForIdle可以保證UI變更后才執行后續代碼,UiObjectNotFoundException的捕捉等。
7)按上面“Android的JUnit測試”描述的第6步執行后在選擇設備界面時選擇Cancel。因為目前Android Studio 1.0不能很好地支持UIAutomator。我們只用它來生成測試apk包。
8)項目的buildoutputsapk下可以找到帶有test字樣的apk包,如圖2-23所示。
9)將Android手機連接電腦,使用下列命令將apk包推送到手機上:
adb push app-debug-test-unaligned.apk /sdcard/test.apk``` 10)使用下列命令進行UI Automator 測試: adb shell uiautomator runtest /sdcard/test.apk 11)上述命令執行完畢后觀察手機,能發現UI被自動進行了操作。等待操作完成后,查看測試結果,如圖2-24所示。<div style="text-align: center"><img src="https://yqfile.alicdn.com/e3a34ed41adec631fe29cb1b7d44b275ca775bba.png" width="" height=""> </div>由于篇幅所限,更具體的UIAutomator測試方法不再進行介紹。讀者可參考Android官方文檔進行學習。 3.基于Instrumentation/ UIAutomator的封裝 除了上文提到的兩個谷歌推出的原生UI自動化測試框架外,還有很多基于它們封裝的UI自動化測試框架。其中Robotium、Appium是使用比較廣泛的。 Robotium其實嚴格來說算不上是一個測試框架,它只是一個類庫,提供了更友好的定位控件的方法等,在使用Instrumentation進行自動化測試時,建議使用Robotium類庫提升測試效率。 Appium是一個重量級的測試框架,支持iOS和Android等平臺的自動化測試,支持多語言編寫測試腳本。在Android自動化測試的實現上,它也是基于Instrumentation和UIAutomator的。Appium用Ruby寫的測試腳本示例如圖2-25所示。<div style="text-align: center"><img src="https://yqfile.alicdn.com/634b95e0f7a18f4c3dbcd91303dc8a7a6ce4a1d5.png" width="" height=""> </div>由于篇幅所限,本書不贅述它們具體的使用方法。有興趣的讀者可以自行搜索相關的資料。 ####2.2.1.3 基于系統事件的自動化測試 所有Android操作系統的輸入事件都可以在進入adb shell后通過getevent獲取(需要su),相關示例如圖2-26所示。 這些事件都會存儲在/dev/input/eventX下。每個eventX代表一個輸入外設。例如觸摸屏、鍵盤等,而輸出的每一行代表一個事件,例如某個鍵盤按下,等等(具體每個事件的三個部分代表什么含義請參考Linux相關資料)。因此,我們可以通過解析這些文件,來實現錄制的功能。測試人員可以把自己的操作錄制下來,用一種數據格式記錄。 那么怎么回放錄制的測試腳本呢?我們可以解析錄制的數據,并在adb shell下使用sendevent命令向指定外設一個個發送事件,也可以在adb shell下用input keyevent命令來做。例如,在將Android手機連接計算機后打開一個記事本類程序,進入adb shell,執行:<div style="text-align: center"><img src="https://yqfile.alicdn.com/454621741fe779628747aeb664f6146527f56c3d.png" width="" height=""> </div> Input keyevent 34`
你會發現效果等同于輸入一個F鍵。
基于系統的事件無法對界面上的元素做判斷,只能進行一些驅動類型的工作。因此這個方法不能單獨使用來進行自動化測試。斷言部分需要配合Instrumentation/UIAutomator。
此方法的缺陷是:
不同的設備有不同的分辨率。在A設備下錄制的腳本在B設備下執行可能會產生問題。
不同設備的eventX可能代表不同外設。
這些都是在使用這個方法進行自動化測試的時候需要考慮的問題。
2.2.1.4 基于圖像識別的自動化測試
近年來圖像識別技術有了一定的發展。因此測試人員也開始研究是否可以將此技術應用到自動化測試中。簡單的想法是,如果一個App的各個元素外觀變化不大,而位置變化較為頻繁,或者內部實現(例如UI控件類的變化)改變較為頻繁,使用圖像識別來寫測試腳本的穩定性可能會較高。另外如果斷言是基于圖像的,那么使用圖像識別技術來做自動化測試更為自然和方便。
測試方法舉例:
1)測試人員寫測試腳本,指定需要操作哪些元素(指定圖片相關的特征),并說明怎么操作。
2)使用adb screencap命令截圖。
3)使用圖像識別技術來識別出各個元素的位置。
4)解析測試腳本,找出下個操作步驟。如果測試結束,則退出生成報告。
5)采用某方法進行相應的操作(通過系統事件、機器人手臂等方式驅動),或者進行基于圖像識別的斷言。
6)返回步驟2)。
但是由于使用此方法的優勢只在特定場景能夠體現,局限性較大,再加上圖像識別準確率的問題,目前還沒有被廣泛接受和應用的測試框架出現。在此提及也是拋磚引玉,希望有一天能夠有一個出色的基于圖像識別的Android測試框架問世。
2.2.2 iOS的UI自動化技術
關于iOS的UI自動化,這里結合實例介紹兩個方面的內容,一個是基于Instrument的UI自動化,另一個是目前比較常用的Appium框架。
2.2.2.1 基于Instrument的iOS UI自動化
對于iOS的UI自動化,Instrument 提供了最基本的自動化測試功能。我們可以通過Automation工具實現基本的自動化測試需求。該工具支持真機和模擬器兩種測試方式:
模擬器:執行速度快,無須證書, 測試門檻較低, 但對于一些特定功能如相機、跳轉就無能為力了。
真機:App的所有功能均能自動化實現,但需調試證書,且執行效率低。
下面用一個示例介紹整個使用過程。
下面我們以Xcode 6為例, 介紹使用Automation的步驟。
1)選擇要測試的target, 選定要編譯安裝的平臺,若在真機上測試就選擇真機設備,同時指定好調試證書及對應的provision文件。若在模擬器上測試就選擇模擬器環境,我們這邊指定iPhone6模擬器,如圖2-27所示。
2)在剛才選擇界面,點擊Edit Scheme,指定Profile選項以Debug模式編譯,點擊關閉,如圖2-28所示。
3)點擊Product菜單下的Profile選項來編譯項目工程,如圖2-29所示。
4)等待編譯完成后,彈出Instrument界面,選擇Automation,如圖2-30所示。
5)系統自動選擇模擬器中的測試App,如果要改成真機運行,修改界面上方的測試平臺至真實設備,選擇相應的App即可,如圖2-31所示。
我們可以通過錄制的方式生成測試腳本,切換到Script界面,點擊下方的錄制按鈕,App在模擬器中就啟動了,我們對App的操作,就會被自動錄制成回放腳本,錄制完成后,點擊終止按鈕,結束錄制。點擊運行按鈕,就可以執行回放剛才錄制的操作了,如圖2-32所示。
錄制的方式雖然很方便,但是缺乏靈活性。大多數時候,我們需要自己編寫腳本。我們的測試App是一個很簡單的登錄界面,輸入用戶名panxiaoming,密碼:Ilovetest,就會登錄成功,彈出一個歡迎界面,如圖2-33所示。
如果輸入錯誤的密碼,會提示錯誤信息,如圖2-34所示。
輸入正確的密碼,提示歡迎信息,如圖2-35所示。
我們可以通過logElementTree的方法查看App的UI元素布局。點擊運行,在Editor Log界面中查看這些UI元素,如圖2-36所示。
Editor Log很有用,在這里可以查看腳本中所有的log信息以及斷言結果,同時它會自動記錄點擊操作和一些其他的操作,同時還有截圖,方便查看。
于是我們就可以編寫一個正常登錄的測試腳本,腳本如圖2-37所示。
執行結果如圖2-38所示。
我們看到在自己編寫的腳本中加入邏輯和判斷,使得腳本的可靠性更強,同時log信息可以幫助我們去分析定位問題,這種方式要比簡單錄制強上不少,腳本的語句類似JavaScript,可以到蘋果官網查看具體語法和API。
我們完全可以通過shell腳本去驅動執行Automation的測試用例, 通過定時執行shell腳本來完成我們的自動化測試任務,具體方法如下:
總結
以上是生活随笔為你收集整理的《移动App测试实战》——2.2 App UI层面的自动化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《深入理解Android:卷III A》
- 下一篇: 制造内核崩溃并使用crash分析内核崩溃