构建检测测试

检测测试在 Android 设备上运行,无论该设备是物理设备还是模拟器。因此,它们可以利用 Android 框架 API。因此,检测测试比本地测试提供了更高的保真度,尽管它们的运行速度要慢得多。

我们建议仅在必须针对真实设备的行为进行测试的情况下使用检测测试。AndroidX Test 提供了多个库,使在必要时编写检测测试变得更容易。

设置您的测试环境

在您的 Android Studio 项目中,您将检测测试的源文件存储在module-name/src/androidTest/java/中。此目录在您创建新项目时就已经存在,并且包含一个检测测试示例。

在开始之前,您应该添加 AndroidX Test API,这些 API 允许您快速构建和运行应用的检测测试代码。AndroidX Test 包括一个 JUnit 4 测试运行程序AndroidJUnitRunner,以及用于功能性 UI 测试的 API,例如EspressoUI AutomatorCompose 测试

您还需要为您的项目配置 Android 测试依赖项,以便使用 AndroidX Test 提供的测试运行程序和规则 API。

在应用的顶层build.gradle文件中,您需要将这些库指定为依赖项

dependencies {
    androidTestImplementation "androidx.test:runner:$androidXTestVersion"
    androidTestImplementation "androidx.test:rules:$androidXTestVersion"
    // Optional -- UI testing with Espresso
    androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
    // Optional -- UI testing with UI Automator
    androidTestImplementation "androidx.test.uiautomator:uiautomator:$uiAutomatorVersion"
    // Optional -- UI testing with Compose
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
}

您可以在AndroidX 发行说明Compose UI 发行说明 中找到最新版本。

要使用 JUnit 4 测试类并访问测试过滤等功能,请确保将AndroidJUnitRunner 指定为项目中的默认测试检测运行程序,方法是在应用的模块级build.gradle文件中包含以下设置

android {
    defaultConfig {
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
}

创建一个检测测试类

您的检测测试类应该是一个 JUnit 4 测试类,类似于“如何构建本地测试”部分中描述的类。

要创建检测 JUnit 4 测试类,请将AndroidJUnit4 指定为您的默认测试运行程序。

以下示例显示了如何编写检测测试以验证Parcelable 接口是否为LogHistory 类正确实现

Kotlin

import android.os.Parcel
import android.text.TextUtils.writeToParcel
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

const val TEST_STRING = "This is a string"
const val TEST_LONG = 12345678L

// @RunWith is required only if you use a mix of JUnit3 and JUnit4.
@RunWith(AndroidJUnit4::class)
@SmallTest
class LogHistoryAndroidUnitTest {
    private lateinit var logHistory: LogHistory

    @Before
    fun createLogHistory() {
        logHistory = LogHistory()
    }

    @Test
    fun logHistory_ParcelableWriteRead() {
        val parcel = Parcel.obtain()
        logHistory.apply {
            // Set up the Parcelable object to send and receive.
            addEntry(TEST_STRING, TEST_LONG)

            // Write the data.
            writeToParcel(parcel, describeContents())
        }

        // After you're done with writing, you need to reset the parcel for reading.
        parcel.setDataPosition(0)

        // Read the data.
        val createdFromParcel: LogHistory = LogHistory.CREATOR.createFromParcel(parcel)
        createdFromParcel.getData().also { createdFromParcelData: List<Pair<String, Long>> ->

            // Verify that the received data is correct.
            assertThat(createdFromParcelData.size).isEqualTo(1)
            assertThat(createdFromParcelData[0].first).isEqualTo(TEST_STRING)
            assertThat(createdFromParcelData[0].second).isEqualTo(TEST_LONG)
        }
    }
}

Java

import android.os.Parcel;
import android.util.Pair;
import androidx.test.runner.AndroidJUnit4;
import com.google.common.truth.Truth.assertThat;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

// @RunWith is required only if you use a mix of JUnit3 and JUnit4.
@RunWith(AndroidJUnit4.class)
public class LogHistoryAndroidUnitTest {

    public static final String TEST_STRING = "This is a string";
    public static final long TEST_LONG = 12345678L;
    private LogHistory mLogHistory;

    @Before
    public void createLogHistory() {
        mLogHistory = new LogHistory();
    }

    @Test
    public void logHistory_ParcelableWriteRead() {
        // Set up the Parcelable object to send and receive.
        mLogHistory.addEntry(TEST_STRING, TEST_LONG);

        // Write the data.
        Parcel parcel = Parcel.obtain();
        mLogHistory.writeToParcel(parcel, mLogHistory.describeContents());

        // After you're done with writing, you need to reset the parcel for reading.
        parcel.setDataPosition(0);

        // Read the data.
        LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);
        List<Pair<String, Long>> createdFromParcelData
                = createdFromParcel.getData();

        // Verify that the received data is correct.
        assertThat(createdFromParcelData.size()).isEqualTo(1);
        assertThat(createdFromParcelData.get(0).first).isEqualTo(TEST_STRING);
        assertThat(createdFromParcelData.get(0).second).isEqaulTo(TEST_LONG);
    }
}

运行检测测试

可对真实设备或模拟器运行 Instrumentation 测试。在 Android Studio 指南中,您可以学习如何

其他资源

UI 测试通常是 Instrumentation 测试,用于验证 UI 的正确行为。它们使用 EspressoCompose Test 等框架。要了解更多信息,请阅读UI 测试指南

有关使用 Instrumentation 测试的更多信息,请参阅以下资源。

示例

Codelab