文章一部分轉(zhuǎn)載自InfoQ:http://www.infoq.com/cn/news/2013/10/google-espresso-testing/
一部分轉(zhuǎn)載自 http://www.devtf.cn/?p=168
感謝原創(chuàng)作者,我這里只是整理學習一下,如有不妥,請告知我一下。??

Google開源了Espresso,這是一種Android自動化測試框架,Espresso 是在2013年的 GTAC 上首次提出,目的是讓開發(fā)人員能夠快速地寫出簡潔,美觀,可靠的 Android UI 測試。使測試人員可以在云中x86機器的多線程環(huán)境里運行測試,并解決了關(guān)于UI測試的并發(fā)問題。
由于Android設(shè)備數(shù)量和種類眾多,在真實的設(shè)備上運行測試非常耗時,而且成本很高。一種解決方案是在模擬器上執(zhí)行測試。模擬器是一個可控的環(huán)境,支持多種OS版本、屏幕尺寸和內(nèi)存限制。這種方法可以捕獲大部分代碼Bug,剩下的Bug可以留給真實設(shè)備測試和人工測試去發(fā)現(xiàn)。
模擬器的問題是執(zhí)行速度,其中,在模擬的ARM CPU上運行Android是一個瓶頸。為了解決這個問題,Google已經(jīng)創(chuàng)建了可以直接在x86硬件上運行的Android版本,并使用了VM加速。另一個瓶頸是Android的啟動時間。該問題已經(jīng)通過抓取OS快照并執(zhí)行快照得以解決。該方法可以在很短的時間內(nèi)提供期望的OS和應(yīng)用程序配置。早在今年3月份,Google就已經(jīng)使用該方法完成了8200萬次Android測試。
通過比較在Nexus 4和模擬器上的測試發(fā)現(xiàn),后者需要真實設(shè)備上測試時間的65%來完成測試。因此,一個好的模擬器似乎已經(jīng)解決了自動化測試問題。但是,還有另一塊絆腳石。自動化測試使用Android的Instrumentation API,這些API的調(diào)用在一個與UI線程不同的線程中運行,因此,使用自動化方法測試用戶界面會導致嚴重的并發(fā)問題,進而產(chǎn)生不一致不可靠的測試結(jié)果。Google對這個問題的解決方案是Espresso,它是一個測試框架,能夠使UI測試在多線程環(huán)境中安全地運行,并移除了關(guān)于編寫測試的大部分樣板代碼。Espresso可以跨各種移動設(shè)備工作,包括電話、電視、智能眼鏡、汽車等。它還可以跨不同屏幕尺寸和內(nèi)存大小、多個API版本以及不同網(wǎng)絡(luò)工作。據(jù)Espresso幕后團隊介紹,他們的解決方案捕獲了Android和應(yīng)用程序中99%的Bug,只給真實設(shè)備測試和人工測試留下了少數(shù)Bug,減少了整體的測試工作量。
Espresso有以下幾個通用組件:
“Espresso”類提供的“onView”和“onData”方法,僅可用于特定接口上測試最優(yōu)數(shù).
ViewMatchers包含一個實現(xiàn)了Matcher <? super View>接口的對象集合. 使用該類你可以收集或是檢查View元素.例如,通過文本 “7” 獲取一個View元素(Button).
ViewActions包含了一組viewAction對象,儲存了將要在View上執(zhí)行的動作. 這些動作被傳遞給ViewInteraction.perform方法,也許包含更多的動作. For 例如, 點擊一下View元素(Button).
ViewAssertions包含ViewAssertion集合,用于對Views進行檢查.
下面是Espresso中斷言視圖未顯示的測試示例:
onView(withId(R.id.bottom_left)).check(matches(not(isDisplayed())));
讀者可以在這里找到其它測試示例。
好消息,去年谷歌推出了集成Espresso的Testing Support Library.因此,讓我們通過實現(xiàn)Espresso開始吧.
為了方便解釋, 我們要編寫一些測試用例來測試Android calculator application這個App. 先來實現(xiàn)一個測試“6”x“7”等于“42”是否正確的普通測試場景。
定義test runner
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545}span.s1 {font: 12.0px 'PingFang SC'}
使用Espresso我們首先需要定義這些測試用例。Espresso使用新的名為AndroidJUnitRunner的測試用例于“InstrumentationTestRunner”和“GoogleInstrumentationTestRunner”,運行JUnit3和JUnit4來測試你的Android應(yīng)用程序。
首先將依賴項添加到你的build.gradle文件中, 這里假設(shè)你已經(jīng)安裝好了Testing Support Library.
gradledependencies {
androidTestCompile ‘com.android.support.test:testing-support-lib:0.1’
}
然后添加測試用例到你的build.gradleandroid.defaultConfig配置中
defaultConfig {
...
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
編寫測試
你可能已經(jīng)想到了,測試類必須在src\androidTest\com.example.package.tests
中.包com.example.package是在AndroidManifest文件中指定的屬性.
每一個測試類還必須繼承抽象類ActivityInstrumentationTestCase2并且使用默認測試的 Activity 作為泛型.
它還需要通過super()方法傳遞給父類.要使被測試的Activity被測試框架調(diào)用,只需要在setup方法中同步調(diào)用getActivity()
方法.
public class FunctionalInstrumentationTest extends ActivityInstrumentationTestCase2<ActivityToTest> {
public FunctionalInstrumentationTest() {
super(ActivityToTest.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
getActivity();
}
}
正如前面提到的,我們想要檢查“6”x“7”是否等于“42”.
public void testAnswer_to_the_Ultimate_Question_of_Life_the_Universe_and_Everything() {
onView(withText("7")).perform(click());
onView(withText("×")).perform(click());
onView(withText("6")).perform(click());
onView(withText("=")).perform(click());
onView(withId(R.id.resText)).check(matches(withText("42")));
}
你可能已經(jīng)注意到,這個示例是使用靜態(tài)導入.這樣做完全是為了使代碼更易于閱讀.
其他你可能會用到的操作:
- pressBack(); to simulate the use of the “back” button,
- isDisplayed(); to check if an element is being shown and
- scrollTo(); to scroll to an element.
- pressBack(); 模擬后退按鈕
- isDisplayed(); jian檢查某個元素是否顯示
- scrollTo(); 滾動到另外一個元素
運行測試
現(xiàn)在我們做做有趣的,運行測試.這可以通過gradle clean assembleDebug connectedAndroidTest從命令行運行,或者使用Android Studio:
- 打開Run菜單 | Edit Configurations
- 添加一個新的Android Tests configuration
- 選擇你需要測試的Module
- 定義我們的測試用例:
android.support.test.runner.AndroidJUnitRunner
Google使用Espresso測試了他們自己的超過30個應(yīng)用程序,包括G+、Maps和Drive。