本機測試會直接在您的工作站執行,而非 Android 裝置或模擬器因此,它會使用您的本機 Java 虛擬機器 (JVM), 執行測試,而非 Android 裝置本機測試可讓您評估 能更快速地偵測應用程式邏輯但無法與 Android 架構會限制您可以執行的測試類型。
單元測試會驗證一小段程式碼 ( 測試。方法是執行程式碼並檢查結果。
單元測試通常很簡單,但如果單元測試 處於測試狀態的設計並未考量可測試性。
- 您要驗證的程式碼必須可供測試存取。適用對象 例如,您無法直接測試私人方法。相反地 透過公用 API 存取
- 如要在「隔離」中執行單元測試,請確認單元的依附元件。 測試中的元件必須替換為您控制的元件,例如 其他的測試替身。如果您的程式碼依賴 Android 架構
如要瞭解 Android 常見的單元測試策略,請參閱這篇文章 測試。
本機測試位置
根據預設,本機單元測試的來源檔案會放在
module-name/src/test/
。您在建立新的目錄時,已有這個目錄
建立專案
新增測試依附元件
您也需要為專案設定測試依附元件,才能使用 JUnit 測試架構提供的標準 API。
如要這麼做,請開啟應用程式模組的 build.gradle
檔案,然後指定以下項目
做為依附元件請使用 testImplementation
函式來表示
套用至本機測試來源集,而非應用程式:
dependencies {
// Required -- JUnit 4 framework
testImplementation "junit:junit:$jUnitVersion"
// Optional -- Robolectric environment
testImplementation "androidx.test:core:$androidXTestVersion"
// Optional -- Mockito framework
testImplementation "org.mockito:mockito-core:$mockitoVersion"
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
// Optional -- Mockk framework
testImplementation "io.mockk:mockk:$mockkVersion"
}
建立本機單元測試類別
本機單元測試類別可用來編寫為 JUnit 4 測試類別。
方法是建立包含一或多個測試方法的類別,通常為
module-name/src/test/
。測試方法以 @Test
註解開始
包含程式碼,用於練習及驗證元件的單一部分
。
以下範例說明如何實作本機單元測試類別。
嘗試驗證的emailValidator_correctEmailSimple_returnsTrue()
測試方法
isValidEmail()
:這是應用程式內的方法。測試函式會傳回
如果isValidEmail()
也傳回 true,則為 true。
Kotlin
import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class EmailValidatorTest { @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")) } }
Java
import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")); } }
建議您建立可讀取的測試,以評估應用程式中的元件是否
應用程式會傳回預期結果。建議您使用斷言程式庫,例如
格式為 junit.Assert、Hamcrest,或
Truth:上方的程式碼片段舉例說明
junit.Assert
。
可模擬的 Android 程式庫
執行本機單元測試時,Android Gradle 外掛程式會包含 內含 Android 架構的所有 API 的程式庫, 專案中使用的版本程式庫存放了所有公開方法和 這些 API 的類別中,但方法中的程式碼已移除。如果有任何 方法存取時,此測試會擲回例外狀況。
這可讓您在參照 Android 中的類別時建立本機測試
例如 Context
更重要的是,您可以使用模擬
與 Android 類別聯手
模擬 Android 依附元件
常見的問題是找出類別正在使用字串資源。你可以
呼叫 Context
中的 getString()
方法,即可取得字串資源
類別然而,本機測試無法使用 Context
或其任何方法,
隸屬於 Android 架構在理想情況下,對 getString()
的呼叫會是
中移出課程,但這並不總是實際。解決方法是
建立 Context
的模擬或虛設常式,且其會在其下列情況傳回相同的值
叫用 getString()
方法。
使用可模擬的 Android 程式庫和模擬架構,例如 Mockito 或 MockK,即可將 在單元測試中,Android 類別模擬的行為。
如要使用 Mockito 在本機單元測試中新增模擬物件,請按照下列步驟操作: 程式設計模型
- 在
build.gradle
檔案中加入 Mockito 程式庫依附元件,如 「設定測試環境」一文所述。 - 在單元測試類別定義的開頭,將
@RunWith(MockitoJUnitRunner.class)
註解。這個註解會指出 透過 Mockito 測試執行器來驗證您的架構使用方式是否正確, 可簡化模擬物件的初始化作業。 - 如要為 Android 依附元件建立模擬物件,請新增
@Mock
註解 。 - 如要虛設依附元件的行為,您可以指定條件並
使用
when()
和thenReturn()
,符合條件時傳回的值 方法。
以下範例說明如何建立使用模擬圖的單元測試
Kotlin 中的 Context
物件使用 Mockito-Kotlin 建立。
import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
private const val FAKE_STRING = "HELLO WORLD"
@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {
@Mock
private lateinit var mockContext: Context
@Test
fun readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
val mockContext = mock<Context> {
on { getString(R.string.name_label) } doReturn FAKE_STRING
}
val myObjectUnderTest = ClassUnderTest(mockContext)
// ...when the string is returned from the object under test...
val result: String = myObjectUnderTest.getName()
// ...then the result should be the expected one.
assertEquals(result, FAKE_STRING)
}
}
如要進一步瞭解如何使用 Mockito 架構,請參閱 Mockito API
參照和 SharedPreferencesHelperTest
類別中的
程式碼範例。另外,也請嘗試使用 Android Testing Codelab。
錯誤:「方法 ... 未模擬」
如果您嘗試存取模擬 Android 程式庫的任何
傳回給 Error: "Method ... not mocked
訊息的方法。
如果擲回的例外狀況對測試造成問題,您可以更改
就會根據
傳回類型。如要這麼做,請在專案的
Groovy 中的頂層 build.gradle
檔案:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}