原文出處https://www.toutiao.com/i6473606106970063374/
原文作者是今日頭條的:一個字頭的誕生
在此感謝原文作者的無私分享!
移動App自動化測試(一)
目前移動App的自動化測試框架比較多,比如:Robotium、Expresso等,很多大公司甚至都會有自己的一套自動化測試框架。這篇文章簡單Android自動化測試框架,iOS自動化測試框架也會少量提到。
-
Monkey是Android SDK自帶的測試工具,在測試過程中會向系統發送偽隨機的用戶事件流,如按鍵輸入、觸摸屏輸入、手勢輸入等),實現對正在開發的應用程序進行壓力測試,也有日志輸出。實際上該工具只能對程序做一些壓力測試,由於測試事件和數據都是隨機的,不能自定義,所以有很大的局限性。
-
MonkeyRunner也是Android SDK提供的測試工具。嚴格意義上來說MonkeyRunner其實是一個Api工具包,比Monkey強大,可以編寫測試腳本來自定義數據、事件。缺點是腳本用Python來寫,對測試人員來說要求較高,有比較大的學習成本。
-
Instrumentation是早期Google提供的Android自動化測試工具類,雖然在那時候JUnit也可以對Android進行測試,但是Instrumentation允許你對應用程序做更為復雜的測試,甚至是框架層面的。通過Instrumentation你可以模擬按鍵按下、抬起、屏幕點擊、滾動等事件。Instrumentation是通過將主程序和測試程序運行在同一個進程來實現這些功能,你可以把Instrumentation看成一個類似Activity或者Service並且不帶界面的組件,在程序運行期間監控你的主程序。缺點是對測試人員來說編寫代碼能力要求較高,需要對Android相關知識有一定了解,還需要配置AndroidManifest.xml文件,不能跨多個App。
-
UiAutomator也是Android提供的自動化測試框架,基本上支持所有的Android事件操作,對比Instrumentation它不需要測試人員了解代碼實現細節(可以用UiAutomatorviewer抓去App頁面上的控件屬性而不看源碼)。基於Java,測試代碼結構簡單、編寫容易、學習成本,一次編譯,所有設備或模擬器都能運行測試,能跨App(比如:很多App有選擇相冊、打開相機拍照,這就是跨App測試)。缺點是只支持SDK 16(Android 4.1)及以上,不支持Hybird App、WebApp。
-
Espresso是Google的開源自動化測試框架。相對於Robotium和UIAutomator,它的特點是規模更小、更簡潔,API更加精確,編寫測試代碼簡單,容易快速上手。因為是基於Instrumentation的,所以不能跨App。配合Android Studio來編寫測試的簡單例子
-
Selendroid:也是基於Instrumentation的測試框架,可以測試Native App、Hybird App、Web App,但是網上資料較少,社區活躍度也不大。
-
Robotium也是基於Instrumentation的測試框架,目前國內外用的比較多,資料比較多,社區也比較活躍。缺點是對測試人員來說要有一定的Java基礎,了解Android基本組件,不能跨App。
-
Athrun是淘寶出的一個移動測試框架/平台,同時支持iOS和Android。Android部分也是基於Instrumentation,在Android原有的ActivityInstrumentationTestCase2類基礎上進行了擴展,提供一整套面向對象的API。這里有詳細介紹。
-
UIAutomation是iOS平台下的測試框架,目前用的比較多的框架。
-
Appium是最近比較熱門的框架,社區也很活躍。后一章我會重點介紹這個自動化測試框架。
移動App自動化測試(二)
上一篇介紹了App自動化測試的目前主流的幾種方式,那么這篇我就來介紹下Appium
什么是Appium?
Appium是Sauce Labs公司的一個移動測試框架,該公司專注於Web、Mobile和桌面應用的自動化測試,為企業開發者提供Web應用測試平台。
它的優點:
-
開源;
-
支持Native App、Hybird App、Web App;
-
支持Android、iOS、Firefox OS;
-
Server也是跨平台的,你可以使用Mac OS X、Windows或者Linux;<!--more-->
它的哲理是:
-
用Appium自動化測試不需要重新編譯App;
-
支持很多語言來編寫測試腳本,Java、Javascript、PHP、Python、C#、Ruby等主流語言;
-
不需要為了自動化測試來重造輪子,因為擴展了WebDriver。(WebDriver是測試WebApps的一種簡單、快速的自動化測試框架,所以有Web自動化測試經驗的測試人員可以直接上手);
-
移動端自動化測試應該是開源的;
它的設計理念:
-
Client/Server架構,運行的時候Server端會監聽Client端發過來的命令,翻譯這些命令發送給移動設備或模擬器,然后移動設備或模擬器做出響應的反應。正是因為這種架構,所以Client可以使用Appium client libraries多種語言的測試腳本,而且Server端完全可以部署在服務器上,甚至雲服務器。
-
Session,每個Client連接到Server以后都會有一個Session ID,而且Client發送命令到Server端都需要這個Session ID,因為這個seesion id代表了你所打開的瀏覽器或者是移動設備的模擬器。所以你甚至可以打開N個Session,同時測試不同的設備或模擬器。
-
Desired Capabilities,其實就是一個鍵值對,設置一些測試的相關信息來告訴Server端,我們需要測試iOS、還是Android,或者換是WebApp等信息。
-
Appium Server,使用Node.js寫的,所以可以直接用NPM來進行安裝。
-
Appium Client,可以使用Java、PHP、Python、Javascript、C#、Ruby等主流語言來編寫測試用例。
相關限制:
-
如果你在Windows使用Appium,你沒法使用預編譯專用於OS X的.app文件,因為Appium依賴OS X專用的庫來支持iOS測試,所以在Windows平台你不能測試iOS Apps。這意味着你只能通過在Mac上來運行iOS測試。
總結:
-
在iOS部分是封裝了UIAutomation;Android 4.2以上是用UiAutomator,Android 2.3 ~ 4.1用的是 Instrumentation,也就說Appium同時封裝了UiAutomator和Instrumentation。所以Appium擁有了以上幾大框架的所有優點:能跨App,支持Native App、Hybird App、Web App的測試;不僅支持N種語言來編寫你的測試腳本,而且可以讓開發人員完全脫離源代碼來編寫。
移動App自動化測試(三)
Appium Server端的簡單安裝
Appium是支持Mac、Windows和Linux的。
-
安裝Node.js:Mac推薦使用Homebrew,Windows可以直接官網下載;如果是Windows用戶,把你的安裝路徑添加到環境變量方便使用(默認是在C:Program FilesNodejs)npm。
-
安裝Git。
-
安裝JDK,並設置JAVA_HOME環境變量。
-
安裝Android SDK,並設置ANDROID_HOME環境變量;把sdk下的tools和platform-tools也設置環境變量。
安裝好以上所有依賴,就可以安裝Appium Server了。Windows和Mac下都有2種使用安裝方式:
-
使用命令行安裝:
$ npm install -g appium$ appium &
2. 或者直接下載GUI桌面應用。
Appium Server配置和使用
以下步驟以Mac下的Appium GUI為例(Windows下的Appium GUI使用可以參考官網文檔):
-
打開Appium,點擊Doctor按鈕。可以檢測上面安裝依賴項是否成功安裝

2.然后點擊Android圖標的配置,選擇你要測試的Apk包。一旦選擇好APK包,這里的Package和Launch Activity直接會在下拉框顯示出來,個人覺得這是Appium框架的非常大的優點,無需APK源碼,減少與開發人員的溝通成本。

3. 然后配置Advanced中的SDK路徑和簽名keystore信息(其實可以不配置簽名這一項也可以測試APK包,但是簽名項驗證測試也還是非常重要的)。

4. 其他設置可以暫時都默認,然后直接運行Launch。運行的相關信息和錯誤日志都會直接顯示在這里:

到這一步為止Appium Server已經成功啟動了。
Appium Client的配置
Appium Client的安裝可以用Maven來構建:
-
Maven配置代碼:
<dependency> <groupId>io.appium</groupId> <artifactId>java-client</artifactId> <version>2.1.0</version></dependency>
2. 或者直接下載jar包,添加到測試項目中。
利用UiAutomatorviewer來獲取控件的信息
編寫測試用例需要模擬各種按鍵點擊、滾動、輸入文字等信息,前面已經提到使用Appium的測試框架可以脫離源代碼,那么是如何獲取Apk上的控件信息呢?這里介紹UiAutomatorviewer這個Android SDK自帶的工具。
-
如果Android SDK下的tools路徑有添加到環境變量,直接可以在命令行輸入:
$ uiautomatorviewer
沒有添加環境變量,直接在SDK目錄tools/下面有個uiautomatorviewer,雙擊打開。
2. 把要測試的Apk安裝到模擬器或者手機設備中,如果是手機設備用USB連接到PC。
3.然后使用uiautomatorviewer查看控件信息,用我自己的Demo為例:

從右下控件屬性框可以看到控件的任何屬性。下一篇我將會為大家介紹如何利用這些屬性編寫自動化測試腳本
移動App自動化測試(四)
通過之前幾篇大家應該對App自動化測試有個基本了解,也對Appium這個框架有了一定認識。
這一篇是這一系列的最后一篇,教大家怎么寫一個測試腳本,用的語言是Java。
我用Java寫了3個測試腳本,分別測試Native App、Hybird App、Web App。用TestNG單元測試框架。
測試Native App
一個TestNG測試腳本需要3個必要的部分:
-
setup(),用於測試前初始化工作:<!--more-->
@BeforeClasspublic void setup() throws Exception {//你要測試的APKFile appDir = new File("Apk");File app = new File(appDir, "Kuozhiv2.apk");DesiredCapabilities capabilities = new DesiredCapabilities();capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "");//測試平台capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");capabilities.setCapability(MobileCapabilityType.DEVICE_NAME,"Google_Nexus_4");//Android版本capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");//Package namecapabilities.setCapability(MobileCapabilityType.APP_PACKAGE,"com.edusoho.kuozhi");//Launch Activitycapabilities.setCapability(MobileCapabilityType.APP_ACTIVITY,".KuozhiActivity");capabilities.setCapability(MobileCapabilityType.APP,app.getAbsolutePath());driver = new AndroidDriver(new URL("//127.0.0.1:4723/wd/hub"),capabilities);driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);System.out.print("App is launched!");}
-
tearDown(),用於測試完畢清理工作:
@AfterClasspublic void tearDown() throws Exception {driver.quit();}
-
至少1個test()測試用例:
@Testpublic void splashTest() throws Exception {Thread.sleep(2000);int Y = driver.manage().window().getSize().getHeight();int X = driver.manage().window().getSize().getWidth();int sX = (int) (X * 0.8);int sY = (int) (Y * 0.5);int eX = (int) (X * 0.2);int eY = sY;int duration = 600;//第一個模擬滑動driver.swipe(sX, sY, eX, eY, duration);//第二個模擬滑動driver.swipe(sX, sY, eX, eY, duration);WebElement enterMainActivityElement = driver.findElement(By .id("com.edusoho.kuozhi:id/splash_ok_btn"));enterMainActivityElement.click();WebElement enterSchoolElement = driver.findElement(By .id("com.edusoho.kuozhi:id/qr_other_btn"));enterSchoolElement.click();}
這個測試NativeApp的腳本比較簡單:滑動2次Splash,點擊進入,登錄等事件。注:抓取控件可以根據ID,如果控件沒有ID還可以用XPath。
測試效果:

測試Hybird App
在測試Hybird App的時候,有一點需要注意:
只有測試設備或者模擬器版本是Android 4.4(API 19)及以上,Appium才能探測到一個Activity中的WebView控件,如果低於Android 4.4(API 19),那么改用Selendroid模式。因為在4.4上WebView是Chromium內核,之前都是Webkit內核。
如何定位WebView中頁面的元素?
UiAutomatorViewer只能定位Activity中的UI元素,WebView已經是最小單元UI,不能解析WebView中頁面元素。這里我使用Chrome DevTools中的inspect來解析WebView中的UI元素。

-
setup()初始化部分代碼:
@BeforeClasspublic void setup() throws Exception {//other code ...//如果你測試的設備的Android版本低於4.4,那么Automation Name要改成"Selendroid",Appium Server端也要改成"Selendroid"capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"Appium");//other code ...}
-
test()測試用例部分代碼:
@Testpublic void webViewLogin() throws Exception {//other code ...Set<String> contextNames = driver.getContextHandles();for (String contextName : contextNames) { System.out.println("--->" + contextName); if (contextName.contains("NATIVE_APP")) { srtActivityContextString = contextName; } if (contextName.contains("WEBVIEW")) { strWebViewContext = contextName; }}driver.context(strWebViewContext);//把driver切換到WebView的context,再抓取WebView內頁面的UI元素//other code ...}
測試效果:

測試Web App
嚴格來說,這部分測試可以交給Web測試人員,因為測試WAP頁面,也是Web測試人員的一部分工作。不過作為App測試人員,也可以掌握這部分技能。
用Appium框架測試WebApp的時候有以下幾點需要注意:
-
目前Appium的WebApp測試只支持Chrome瀏覽器。
-
Chrome在x86模擬器上除非自己編譯,否則是裝不上或者存在各種問題的。請用ARM模擬器或真機,或者直接使用selenium測試框架直接對Web進行測試。因為我用的Genymotion模擬器,是x86的,所以發現了這個坑。可以在官網文檔看到這個說明。
-
setup()測試初始化之前,需要指定瀏覽器名稱,如下代碼:
@BeforeClasspublic void setup() throws Exception {//other code ...capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "chrome");//other code ...}
-
driver需要指定webview的url,如下代碼:
@Testpublic void registerTest() throws Exception {//other code ...driver.get(web_app_url;}
測試效果:

通過這3個測試腳本,我們應該基本掌握了移動App測試腳本的編寫。
原文出處https://www.toutiao.com/i6473606106970063374/
原文作者是今日頭條的:一個字頭的誕生
在此感謝原文作者的無私分享!
