原文:https://developer.android.com/training/testing/unit-testing/local-unit-tests.htmlhtml
若是你的單元測試沒有依賴或者只有簡單的Android依賴,則應該在本地開發機器上運行測試。這種測試方法很是高效,由於它能夠幫助你避免每次運行測試時將目標應用程序和單元測試代碼加載到真機或模擬器上的開銷。所以,運行單元測試的執行時間大大減小了。經過這種方法,你一般使用mock框架(如Mockito)來完成任何依賴關係。java
在你的Android Studio項目中,必須將本地單元測試的源文件存儲在module-name/src/test/java/ 目錄中。在建立新項目時,該目錄已經存在。android
你還須要配置項目的測試依賴,以使用JUnit 4框架提供的標準API。若是你的測試須要與Android依賴關係進行交互,請包含Mockito庫以簡化本地單元測試。要了解有關在本地單元測試中使用模擬對象的更多信息,請參閱模擬Android依賴關係。git
在你的App程序的目錄下找到build.gradle文件中,將這些庫指定爲依賴項:github
dependencies { // Required -- JUnit 4 framework testCompile 'junit:junit:4.12' // Optional -- Mockito framework testCompile 'org.mockito:mockito-core:1.10.19' }
你的本地單元測試類應該寫成一個JUnit 4測試類。 JUnit是Java最流行和普遍使用的單元測試框架。這個框架的最新版本,JUnit 4,容許你用比前一版本更清晰,更靈活的方式編寫測試。與之前的基於JUnit 3的Android單元測試方法(使用JUnit 4)不一樣,你不須要擴展junit.framework.TestCase類。也不須要在測試方法名稱前加上「test」關鍵字,或者使用junit.framework或junit.extensions包中的任何類。編程
要建立基本的JUnit 4測試類,請建立一個包含一個或多個測試方法的Java類。 測試方法從 @Test
註釋開始,包含代碼來練習和驗證要測試的組件中的單個功能。框架
如下示例顯示瞭如何實現本地單元測試類。 測試方法emailValidator_CorrectEmailSimple_ReturnsTrue
驗證被測試的應用程序中的isValidEmail()
方法是否返回正確的結果。工具
import org.junit.Test; import java.util.regex.Pattern; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertThat(EmailValidator.isValidEmail("name@email.com"), is(true)); } ... }
要測試應用程序中的組件是否會返回預期的結果,請使用junit.Assert方法執行驗證檢查(或斷言),以便將待測組件的狀態與某個預期值進行比較。 爲了使測試更具可讀性,可使用Hamcrest匹配器(如is()和equalTo()方法)將返回的結果與指望的結果進行匹配。單元測試
默認狀況下,針對Gradle的Android插件將針對android.jar庫的修改版本執行本地單元測試,該庫不包含任何實際的代碼。 相反,從你的單元測試方法調用Android類拋出一個異常。 這是爲了確保只測試你的代碼,而不依賴於Android平臺的任何特定行爲(你沒有明確地mock)。測試
你可使用mock框架在代碼中刪除外部依賴項,以便以預期的方式輕鬆測試組件與依賴項的交互。 經過用mock對象代替Android依賴關係,能夠將單元測試與Android系統的其他部分分離,同時驗證這些依賴關係中正確的方法被調用。Java的Mockito模擬框架(版本1.9.5及更高版本)提供了與Android單元測試的兼容性。藉助Mockito能夠配置模擬對象以在調用時返回某個特定的值。
要使用此框架將mock對象添加到本地單元測試中,請遵循如下編程模型:
一、在你的 build.gradle 文件中包含Mockito庫依賴項,如設置上面的測試環境中所述。
二、在單元測試類定義的開始處,添加 @RunWith(MockitoJUnitRunner.class)
註釋。 這個註釋告訴Mockito測試運行器驗證你對框架的使用是否正確,而且簡化了你的模擬對象的初始化。
三、要爲Android依賴項建立一個模擬對象,請在字段聲明以前添加@Mock註釋。
四、爲了Stub依賴的行爲,能夠經過使用when()
和return()
方法來知足條件時,能夠指定一個條件和返回值。
如下示例顯示如何建立使用模擬Context對象的單元測試。
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.CoreMatchers.*; import static org.mockito.Mockito.*; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import android.content.SharedPreferences; @RunWith(MockitoJUnitRunner.class) public class UnitTestSample { private static final String FAKE_STRING = "HELLO WORLD"; @Mock Context mMockContext; @Test public void readStringFromContext_LocalizedString() { // Given a mocked Context injected into the object under test... when(mMockContext.getString(R.string.hello_word)) .thenReturn(FAKE_STRING); ClassUnderTest myObjectUnderTest = new ClassUnderTest(mMockContext); // ...when the string is returned from the object under test... String result = myObjectUnderTest.getHelloWorldString(); // ...then the result should be the expected one. assertThat(result, is(FAKE_STRING)); } }
要了解有關使用Mockito框架的更多信息,請參閱示例代碼中的Mockito API參考和SharedPreferencesHelperTest類。
若是您運行測試,從Android SDK調用API,你不會使用mock,可能會收到一個錯誤,說這種方法沒有被模擬。 這是由於用於運行單元測試的android.jar文件不包含任何當前代碼(這些API僅由設備上的Android系統映像提供)。
相反,全部方法默認都會拋出異常。 這是爲了確保你的單元測試你的代碼,而不是依賴於Android平臺的任何特定的行爲(你沒有明確地mock,如Mockito)。
若是拋出的異常說你的測試有問題,能夠更改行爲,以便經過在項目的頂級build.gradle文件中添加如下配置來返回null或零:
android { ... testOptions { unitTests.returnDefaultValues = true } }
注意:將returnDefaultValues屬性設置爲true應該當心。 null / zero返回值能夠在測試中引入迴歸,這些回調很難調試,而且可能容許失敗的測試經過。只能用它做爲最後的手段。
要運行您的本地單元測試,請按照下列步驟操做:
一、經過單擊工具欄中的「 Sync Project」,確保您的項目與Gradle同步。
二、如下列其中一種方式運行測試: