面向UI的單元測試框架:AndroidUITestRunner
這是以前在團隊中寫的一個面向Android應用的測試工具,在團隊中使用效果不錯,現在整理出來在這里分享,希望能夠幫到有需要的人。
AndroidUITestRunner 可以有什么用處?
通常我們使用的單元測試框架都是用來測試一些非UI的邏輯的,如JUnit,CPPUnit。我希望團隊中的成員都要養成寫單元測試的習慣,一方面 單元測試本身就是一份非常好的文檔,另一方面單元測試有助于強迫使你的代碼耦合更加松散(模塊可以獨立測試), 在移動應用開發中我遇到一些這樣的問題。
你知道移動應用一般都是MVC的結構,Mode層面使用JUnit進行單元測試很方便,但是想測試View就無能為力了,或者說View基本上就代 碼中直接實現了。在實際開發的過程中往往產品經理或者設計師會要求程序員實現一種特定的效果,那么我們通常的做法就是創建一大堆Demo工程來演示 View效果很不方便,而且和項目本身也沒有什么實際的聯系回頭還是要拷貝代碼到實際項目中。所以為了更加方便測試項目中的一些界面效果,我便實現了 “AndroidUITestRunner”這么一個工具。你可以把每一個布局或者界面效果寫成測試用例和項目一起構建,然后安裝在你的設備上點擊運行你 的測試用例,讓設計師或產品經理看看你的UI實現是否OK,最重要的是團隊成員可以很快達到并行工作狀態,一部分人寫傳統的測試用例,另外一部分人可以立 刻實現設計師要求UI用例,一旦UI測試用例和傳統的測試用例達到預期,接下來只需要實現Controller部分把Model和View集成進來就好 了。我自己在開發xbrowser 的時候也是使用這個框架,很多需要驗證想法的邏輯都放在了測試用例里面,事實證明無論是開發效率還是代碼穩定性都有很大提升。
AndroidUITestRunner提供了類似JUnit的功能,你只要寫一個以"test"開頭的方法框架就會自動的把這些以"test"開頭的用例組織起來生成一個列表,點擊列表項就可以看到UI的演示效果,如下圖所示。

這是一個測試套件的列表,每個列表包括一系列相關的測試用例。

打開測試套件你將會看到某個測試套件下的測試用例列表,點擊某個測試用例就好看到響應的執行效果。下面介紹如何正好AndroidUITestRunner到你的項目中。
在你的項目中使用UITestRunner
Step 1 從github上下載UITestRunner源碼
git clone https://github.com/examplecode/android-ui-test-runner
Step 2 導入AndroidUITestRunner 到 你的項目中
下面分別介紹了,如何導入AndroidUITestRunner到你的AndroidStdio工程和Eclipse工程中。
導入到AndroidStdio
1. 選擇 File-> New -> Import Module 導入模塊



2. 設置項目依賴 uiTestRunner 模塊



導入UITestRunner 到 Eclipse
1. 導入UiTestRunner




2. 設置項目依賴UiTestRunner模塊



Step 3 在你的項目中添加UITestRunner的聲明
在你自己項目的AndroidManifest.xml中添加以下內容聲明UITestActivity(測試用例的展示界面)
<activity android:name="com.mmbox.uitestrunner.UITestActivity"> <intent-filter> <action android:name="com.mmbox.uitestrunner.Main" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Step 4 創建你自己的測試套件
你可以根據不同的測試類型創建多個測試套件,創建測試套件很簡單只需要在你的項目中新建一個Class從UITestSuite繼承即可(框架會自 動搜索從UITestSuite繼承的所有測試套件并在列表中呈現出來)。建議我們創建一個package來存放所有的測試套件(不是必須只是為了清楚易 于維護,包名可以自己定義) 比如 "com.myapp.testsuites", 下面是一個測試套件的代碼實現。
public class MySampleTestSuite1 extends UITestSuite { public MySampleTestSuite1(Context context) { super(context); // TODO Auto-generated constructor stub } }
Step5 為已有的測試套件添加測試用例
添加測試用例也很簡單,只需要在測試套件中增加一些以 "test" 開頭的 public 方法即可,如以下代碼:
public class MySampleTestSuite1 extends UITestSuite { public MySampleTestSuite1(Context context) { super(context); // TODO Auto-generated constructor stub } public void testSayHello() { Toast.makeText(getContext(), "Hello UITestRunner",Toast.LENGTH_SHORT).show(); } public void testCase1InTestSuite1() { Toast.makeText(getContext(), "testCase1InTestSuite1 is runngin",Toast.LENGTH_SHORT).show(); } public void testCase2InTestSuite1() { Toast.makeText(getContext(), "testCase2InTestSuite1 is runngin",Toast.LENGTH_SHORT).show(); } }
Step6 啟動測試用例
到此我們就完成了一個測試套件及相關的測試用例了,接下來我們看看如何運行測試用例。
運行測試套件要借助于adb命令,首先安裝你的應用到目標設備或模擬器上,并確保你的設備和adb正常連接( adb devices 命令可以發現你的設備) 。接下來只需要執行下面的命令就可以在應用界面中展現你的測試用例。
adb shell am start -a com.mmbox.uitestrunner.Main
一切正常的話你將會看到類似下面的界面,在這里我實現了三個測試套件.

一些簡單的示例
我們除了在測試用例測試一些簡單的邏輯外,還有一個經常需要的場景就是想看看一個布局文件的實際顯示效果,這時候我們沒有必要創建一個新的 Activity來顯示你的View,只需要在測試用例中調用showTestView方法即可. 框架提供了兩個方法 showView,showLayout,分別用于顯示一個View實例和展示一個布局文件。
顯示一個視圖
下面的代碼新增一個測試用例,用來顯示一個Button。
public void testShowSimpleButton() { Button btn = new Button(getContext()); btn.setText("Click Me"); btn.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); showView(btn); }

顯示一個布局文件
下面的代碼用于展示一個布局文件的顯示效果.
public void testShowSimpleLayout() { showLayout(R.layout.show_layout_demo); }
布局文件的源碼如下:
<!-- Demonstrates using nextLeft, nextRight, nextUp and nextDown to get focus behavior that would be difficult with default focus calculation alg.--> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dip"> <Button android:id="@+id/top" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:nextFocusDown="@+id/bottom" android:text="Top"/> <Button android:id="@+id/right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:nextFocusLeft="@+id/left" android:text="Right"/> <Button android:id="@+id/bottom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:nextFocusUp="@+id/top" android:text="Bottom"/> <Button android:id="@+id/left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:nextFocusRight="@+id/right" android:text="Left"/> </RelativeLayout>
展示效果

如果覺得這個東東有用,不妨在github Start 一下搜藏起來, :) 。
來自:http://www.jianshu.com/p/3453b641e594