進階測試設定

在 Android Studio 中進行測試」和「從指令列進行測試」這兩篇文章說明了如何設定及執行基本測試。不過,當應用程式及測試要求條件更為複雜時,您可能需要進一步調整測試設定。舉例來說,可能需要採用進階測試設定,才能執行下列操作:

  • 僅針對特定建構變數執行檢測測試,或是覆寫其資訊清單設定。
  • 變更用於執行測試的建構類型,或設定其 Gradle 選項。
  • 將檢測測試擷取至專屬的測試模組。

此頁面說明在預設設定不符合用途時,如何設定測試的各種方法。

為建構變數建立檢測測試

如果專案包含建構變數與專屬來源集,您可能需要納入對應此來源集的檢測測試。這樣一來,測試程式碼可以維持得井然有序,您也只能執行適用於特定建構變數的測試。

您可以將檢測測試連結至建構變數,方法是將其置於位於 src/androidTestVariantName 的專屬來源集。

src/androidTest/ 來源集中的檢測測試是由所有建構變數共用。為應用程式的「MyFlavor」變化版本建構測試 APK 時,Gradle 會結合 src/androidTest/src/androidTestMyFlavor/ 來源集。

若要在 Android Studio 中為您的建構變數新增測試來源集,請按照下列步驟操作:

  1. 在左側的「Project」(專案) 視窗中,按一下下拉式選單並選取「Project」(專案) 檢視畫面。
  2. 在適當的模組資料夾中,以滑鼠右鍵按一下「src」資料夾,依序點選「Add」(新增) >「Directory」(目錄)
  3. 輸入「androidTestVariantName」做為目錄名稱。舉例來說,如果您有名為「MyFlavor」的建構變數,則目錄名稱應為「androidTestMyFlavor」。然後按一下「OK」(確認)
  4. 在新目錄上按一下滑鼠右鍵,依序點選「Add」(新增) >「Directory」(目錄)
  5. 輸入「java」做為目錄名稱,然後按一下「OK」(確定)

現在,您可以按照新增測試的步驟,在此新來源集中加入測試。出現「Choose Destination Directory」(選擇目的地目錄) 對話方塊時,請選取新的變化版本測試來源集。

下表以檢測設備測試檔案為例,說明其如何存放在應用程式程式碼來源集對應的來源集中。

表 1. 應用程式原始碼和對應的檢測設備測試檔案。

應用程式類別的路徑 相應檢測設備測試類別的路徑
src/main/java/Foo.java src/androidTest/java/AndroidFooTest.java
src/myFlavor/java/Foo.java src/androidTestMyFlavor/java/AndroidFooTest.java

Gradle 建構作業會合併及覆寫不同測試來源集中的檔案,如同對應用程式來源集的操作一樣。在這種情況下,androidTestMyFlavor 來源集中的 AndroidFooTest.java 檔案會覆寫 androidTest 來源集中的版本。背後的原因,在於變種版本來源集的優先順序高於主要來源集。如要進一步瞭解來源集如何合併,請參閱「‎建構設定」一文。

設定檢測資訊清單

檢測測試內建於獨立的 APK,並具有專用的 AndroidManifest.xml 檔案。Gradle 建構測試 APK 時,會自動產生 AndroidManifest.xml 檔案,並使用 <instrumentation> 節點進行設定。Gradle 為您設定這個節點的原因之一,是要確保 targetPackage 屬性會指定受測應用程式的正確套件名稱。如要變更這個節點的部分其他設定,可以在測試來源集中建立另一個資訊清單檔案,或是設定模組層級的 build.gradle 檔案,如以下程式碼範例所示。如需完整的選項清單,請參閱 BaseFlavor API 參考資料。

android {

    ...

    // Each product flavor you configure can override properties in the
    // defaultConfig {} block. To learn more, go to Configure product flavors.

    defaultConfig {

        ...

        // Specifies the application ID for the test APK.
        testApplicationId = "com.test.foo"

        // Specifies the fully-qualified class name of the test instrumentation
        // runner.
        testInstrumentationRunner = "android.test.InstrumentationTestRunner"

        // If set to true, enables the instrumentation class to start and stop profiling.
        // If set to false (default), profiling occurs the entire time the instrumentation
        // class is running.
        testHandleProfiling = true

        // If set to true, indicates that the Android system should run the instrumentation
        // class as a functional test. The default value is false.
        testFunctionalTest = true

    }
}

變更測試建構類型

根據預設,所有檢測設備測試都會針對 debug 建構類型執行。您可以在模組層級 build.gradle 檔案中使用 testBuildType 屬性,變更為其他建構類型。舉例來說,如果您想對 staging 建構類型執行測試,請編輯檔案,如以下程式碼片段所示。

android {

    ...

    testBuildType "staging"

}

設定 Gradle 測試選項

Android Gradle 外掛程式可讓您指定所有或部分測試的特定選項。您可以在模組層級 build.gradle 檔案中,使用 testOptions{} 區塊指定相關選項,變更 Gradle 執行所有測試的方式。

Groovy

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        // Changes the directory where Gradle saves test reports. By default,
        // Gradle saves test reports in the
        // path_to_your_project/module_name/build/outputs/reports/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        reportDir "$rootDir/test-reports"
        // Changes the directory where Gradle saves test results. By default,
        // Gradle saves test results in the
        // path_to_your_project/module_name/build/outputs/test-results/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        resultsDir "$rootDir/test-results"
    }
}

Kotlin

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        // Changes the directory where Gradle saves test reports. By default,
        // Gradle saves test reports in the
        // path_to_your_project/module_name/build/outputs/reports/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        reportDir "$rootDir/test-reports"
        // Changes the directory where Gradle saves test results. By default,
        // Gradle saves test results in the
        // path_to_your_project/module_name/build/outputs/test-results/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        resultsDir = "$rootDir/test-results"
    }
}

如果只要指定本機單元測試的選項,請在 testOptions{} 中設定 unitTests{} 區塊。

Groovy

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            // By default, local unit tests throw an exception any time the code
            // you are testing tries to access Android platform APIs (unless you
            /// mock Android dependencies yourself or with a testing framework like Mockito).
            // However, you can enable the following property so that the test
            // returns either null or zero when accessing platform APIs, rather
            // than throwing an exception.
            returnDefaultValues true

            // Encapsulates options for controlling how Gradle executes local
            // unit tests. For a list of all the options you can specify, read
            // Gradle's reference documentation.
            all {
                // Sets JVM argument(s) for the test JVM(s).
                jvmArgs '-XX:MaxPermSize=256m'

                // You can also check the task name to apply options to only the
                // tests you specify.
                if (it.name == 'testDebugUnitTest') {
                    systemProperty 'debug', 'true'
                }
                ...
            }
        }
    }
}

Kotlin

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            // By default, local unit tests throw an exception any time the code
            // you are testing tries to access Android platform APIs (unless you
            /// mock Android dependencies yourself or with a testing framework like Mockito).
            // However, you can enable the following property so that the test
            // returns either null or zero when accessing platform APIs, rather
            // than throwing an exception.
            returnDefaultValues = true

            // Encapsulates options for controlling how Gradle executes local
            // unit tests. For a list of all the options you can specify, read
            // Gradle's reference documentation.
            all {
                // Sets JVM argument(s) for the test JVM(s).
                jvmArgs = listOf("-XX:MaxPermSize=256m")

                // You can also check the task name to apply options to only the
                // tests you specify.
                if (it.name == "testDebugUnitTest") {
                    systemProperty = mapOf("debug" to "true")
                }
                ...
            }
        }
    }
}

針對檢測測試使用不同的測試模組

如果您希望某個模組專門用於檢測測試,並將其餘程式碼與測試隔離,可以建立獨立的測試模組,並設定與程式庫模組相似的建構版本。若要建立測試模組,請按照下列指示操作:

  1. 建立程式庫模組
  2. 在模組層級 build.gradle 檔案中套用 com.android.test 外掛程式,而非 com.android.library
  3. 按一下「Sync Project」(同步處理專案) 來同步處理專案。

建立測試模組後,您可以在主要或變異來源集 (例如 src/main/javasrc/variant/java) 中加入測試程式碼。如果您的應用程式模組定義多種變化版本,您可以在測試模組中重新建立這些變種版本,而使用變化感知依附元件管理時,測試模組會嘗試在目標模組中測試符合的變化版本。

根據預設,測試模組只會包含及測試偵錯變化版本。不過,您可以建立新的建構類型,以比對經過測試的應用程式專案。若要讓測試模組測試不同的建構類型,而非偵錯類型,請使用 VariantFilter 停用測試專案中的偵錯變化版本,如下所示:

Groovy

android {
    variantFilter { variant ->
        if (variant.buildType.name.equals('debug')) {
            variant.setIgnore(true);
        }
    }
}

Kotlin

android {
    variantFilter {
        if (buildType.name == "debug") {
            ignore = true
        }
    }
}

如果希望測試模組僅以特定變種版本或建構類型的應用程式為目標,您可以使用 matchingFallbacks 屬性,鎖定您要測試的變化版本。這樣一來,測試模組本身就不必設定這些變化版本了。