本文章轉載于搜狗測試
本文轉自簡書,是作者翻譯Google I/0 2015中關于測試的codelab。
目錄
1.概述
2.創建新的Android Studio工程
3.配置支持單元測試的工程
4.創建第一個單元測試
5.運行單元測試
6.配置支持Instrumentation測試的工程
7.為app添加簡單的交互
8.創建并運行Espresso測試
9.祝賀!
1. 概述
在這個codelab中,你將學習如何在Android Studio中配置工程用于測試,在開發機器上編寫并運行單元測試,以及如何在手機上做功能UI測試。
你會學到什么
更新包含JUnit和AndroidTesting Support Library的Gradle構建文件
編寫運行在本機Java虛擬機上的單元測試
編寫運行在手機或者虛擬機上的Espresso測試
你需要什么
Android Studiov1.2+
Android 4.0+的測試設備
2.創建新的Android Studio工程
如果是第一次啟動Android Studio,從歡迎頁選擇“Start a new Android Studio project”。如果已經打開了一個工程,選擇File>New>New Project...
“Create new project”向導會指導整個過程,在第一頁輸入如下內容:
這樣會保證你的代碼同codelab講解的內容具有一致的命名。其他的選項都設置為默認,一路點擊Next直到工程創建完畢。
點擊Run按鈕檢查app是否運行正常,要么從模擬器列表中選擇一個啟動,要么確認開啟了debug模式的設備通過USB同電腦正確連接。
app目前沒有做任何事情,但是屏幕上應該顯示“Hello world!”和app的名字。
3.配置支持單元測試的工程
在寫測試之前,讓我們做下簡單的檢查,確保工程配置正確。
首先,確認在Build Variants窗口內的Test Artifact中選擇了"Unit Tests"。
然后,在工程的src文件夾內創建test和test/java文件夾。需要注意的是,你不能在Android視圖下進行這些操作,要么在系統的文件管理器內創建,要么在工程窗口左上方點擊下拉菜單選擇Project視圖。最終的工程結構應該是這樣的:
最后,打開工程的build.gradle(Module:app)文件,添加JUnit4依賴,點擊Gradle sync按鈕。
dependencies{compilefileTree(dir:'libs',include: ['*.jar'])compile'com.android.support:appcompat-v7:22.1.1'testCompile'junit:junit:4.12'}
當你同步Gradle配置時,可能需要聯網下載JUnit依賴。
4.創建第一個單元測試
現在,萬事俱備,讓我們開始寫第一個測試吧。首先,創建一個非常簡單的被測類:Calculator類。
然后,向類中添加一些基本的算術運算方法,比如加法和減法。將下列代碼復制到編輯器中。不用擔心實際的實現,暫時讓所有的方法返回0。
packagecom.example.testing.testingexample;publicclassCalculator{publicdoublesum(doublea,doubleb){return0; ? ?}publicdoublesubstract(doublea,doubleb){return0; ? ?}publicdoubledivide(doublea,doubleb){return0; ? ?}publicdoublemultiply(doublea,doubleb){return0; ? ?}}
Android Studio提供了一個快速創建測試類的方法。只需在編輯器內右鍵點擊Calculator類的聲明,選擇Go to > Test,然后"Create anew test…"
在打開的對話窗口中,選擇JUnit4和"setUp/@Before",同時為所有的計算器運算生成測試方法
這樣,就會在正確的文件夾內(app/src/test/java/com/example/testing/testingexample)生成測試類框架,在框架內填入測試方法即可。下面是一個示例:
Calculator.java
packagecom.example.testing.testingexample;importorg.junit.Before;importorg.junit.Test;importstaticorg.junit.Assert.*;publicclassCalculatorTest{privateCalculator mCalculator;@BeforepublicvoidsetUp()throwsException{ ? ? ? ?mCalculator =newCalculator(); ? ?}@TestpublicvoidtestSum()throwsException{//expected: 6, sum of 1 and 5assertEquals(6d, mCalculator.sum(1d,5d),0); ? ?}@TestpublicvoidtestSubstract()throwsException{ ? ? ? ?assertEquals(1d, mCalculator.substract(5d,4d),0); ? ?}@TestpublicvoidtestDivide()throwsException{ ? ? ? ?assertEquals(4d, mCalculator.divide(20d,5d),0); ? ?}@TestpublicvoidtestMultiply()throwsException{ ? ? ? ?assertEquals(10d, mCalculator.multiply(2d,5d),0); ? ?}}
5.運行單元測試
終于到運行測試的時候了!右鍵點擊CalculatorTest類,選擇Run > CalculatorTest。也可以通過命令行運行測試,在工程目錄內輸入:
./gradlew test
無論如何運行測試,都應該看到輸出顯示4個測試都失敗了。這是預期的結果,因為我們還沒有實現運算操作。
讓我們修改Calculator類中的sum(double a,double b)方法返回一個正確的結果,重新運行測試。你應該看到4個測試中的3個失敗了。
Calculator.java
publicdoublesum(doublea,doubleb){returna + b;}
作為練習,你可以實現剩余的方法使所有的測試通過。
可能你已經注意到了Android Studio從來沒有讓你連接設備或者啟動模擬器來運行測試。那是因為,位于src/tests目錄下的測試是運行在本地電腦Java虛擬機上的單元測試。編寫測試,實現功能使測試通過,然后再添加更多的測試...這種工作方式使快速迭代成為可能,我們稱之為測試驅動開發。
值得注意的是,當在本地運行測試時,Gradle為你在環境變量中提供了包含Android框架的android.jar包。但是它們功能不完整(所以,打個比方,你不能單純調用Activity的方法并指望它們生效)。推薦使用Mockito等mocking框架來mock你需要使用的任何Android方法。對于運行在設備上,并充分利用Android框架的測試,請繼續閱讀本篇教程的下個部分。
6.配置支持Instrumentation測試的工程
雖然在Android框架內支持運行instrumentation測試,但是目前開發重心主要集中在剛剛發布的作為Android Testing Support Library一部分的新的AndroidJUnitRunner。測試庫包含Espresso,用于運行功能UI測試的框架。讓我們通過編輯build.gradle的相關部分來把它們添加進我們的工程。
build.gradle
apply plugin:'com.android.application'android { ? ?compileSdkVersion22buildToolsVersion"22.0.1"defaultConfig { ? ? ? ?applicationId"com.example.testing.testingexample"minSdkVersion15targetSdkVersion22versionCode1versionName"1.0"http://ADD THIS LINE:testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"} ? ?buildTypes { ? ? ? ?release { ? ? ? ? ? ?minifyEnabledfalseproguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'} ? ?}//ADD THESE LINES:packagingOptions {exclude'LICENSE.txt'}}dependencies{compilefileTree(dir:'libs',include: ['*.jar'])compile'com.android.support:appcompat-v7:22.0.0'//← MAKE SURE IT’S 22.0.0testCompile'junit:junit:4.12'//ADD THESE LINES:androidTestCompile'com.android.support.test:runner:0.2'androidTestCompile'com.android.support.test:rules:0.2'androidTestCompile'com.android.support.test.espresso:espresso-core:2.1'}
重要:由于一些依賴版本沖突,你需要確認com.android.support:appcompat-v7庫的版本號是22.0.0,像上面的代碼片段一樣。
另外,Android Studio可能會提醒你Build Tools 22.0.1沒有安裝。你應該接受修復建議,Studio會為你安裝Build Tools或者在build.gradle中把這行修改成已經安裝在你電腦的版本。
上面的工作完成后,在Build Variants窗口內切換成Android Instrumentation Tests,你的工程應該自動同步。如果沒有,點擊Gradle sync按鈕。
7.為app添加簡單的交互
在使用Espresso進行UI測試前,讓我們為app添加一些Views和簡單的交互。我們使用一個用戶可以輸入名字的EditText,歡迎用戶的Button和用于輸出的TextView。打開res/layout/activity_main.xml,粘貼如下代碼:
activity_main.xml
還需要在MainActivity.java中添加onClick handler:
MainActivity.java
publicvoidsayHello(View v){ ? ?TextView textView = (TextView) findViewById(R.id.textView); ? ?EditText editText = (EditText) findViewById(R.id.editText); ? ?textView.setText("Hello, "+ editText.getText().toString() +"!");}
現在可以運行app并確認一切工作正常。在點擊Run按鈕之前,確認你的Run Configuration沒有設置為運行測試。如需更改,點擊下拉選項,選擇app。
8.創建并運行Espresso測試
在工程的整體視圖上,找到以(androidTest)后綴結尾的包名并創建一個新的Java類。可以將它命名為MainActivityInstrumentationTest,將如下代碼粘貼過去。
MainActivityInstrumentationTest.java
package com.example.testing.testingexample;importandroid.support.test.InstrumentationRegistry;importandroid.support.test.espresso.action.ViewActions;importandroid.support.test.rule.ActivityTestRule;importandroid.support.test.runner.AndroidJUnit4;importandroid.test.ActivityInstrumentationTestCase2;importandroid.test.suitebuilder.annotation.LargeTest;importorg.junit.After;importorg.junit.Before;importorg.junit.Rule;importorg.junit.Test;importorg.junit.runner.RunWith;importstatic android.support.test.espresso.Espresso.onView;importstatic android.support.test.espresso.action.ViewActions.click;importstatic android.support.test.espresso.action.ViewActions.closeSoftKeyboard;importstatic android.support.test.espresso.action.ViewActions.typeText;importstatic android.support.test.espresso.assertion.ViewAssertions.matches;importstatic android.support.test.espresso.matcher.ViewMatchers.withId;importstatic android.support.test.espresso.matcher.ViewMatchers.withText;@RunWith(AndroidJUnit4.class)@LargeTestpublicclassMainActivityInstrumentationTest{privatestaticfinalStringSTRING_TO_BE_TYPED="Peter"; ? ?@RulepublicActivityTestRule mActivityRule = newActivityTestRule<>(MainActivity.class); ? ?@Testpublicvoid sayHello(){ ? ? ? ?onView(withId(R.id.editText)).perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard());//line 1onView(withText("Say hello!")).perform(click());//line 2StringexpectedText ="Hello, "+STRING_TO_BE_TYPED+"!"; ? ? ? ?onView(withId(R.id.textView)).check(matches(withText(expectedText)));//line 3}}
測試類通過AndroidJUnitRunner運行,并執行sayHello()方法。下面將逐行解釋都做了什么:
1.首先,找到ID為editText的view,輸入Peter,然后關閉鍵盤;
2.接下來,點擊Say hello!的View,我們沒有在布局的XML中為這個Button設置id,因此,通過搜索它上面的文字來找到它;
3.最后,將TextView上的文本同預期結果對比,如果一致則測試通過;
你也可以右鍵點擊域名運行測試,選擇Run>MainActivityInstrume...(第二個帶Android圖標的)