首页 > 解决方案 > Android:用于仪器测试的不同 applicationId

问题描述

我的 Android 仪器测试需要修改/清除应用程序数据,因此我希望它们使用单​​独的 applicationId,以便将私有数据目录和共享首选项等内容分开。

Android 文档中,我阅读了以下内容

默认情况下,构建工具使用给定构建变体的应用程序 ID 将应用程序 ID 应用到您的仪器测试 APK,并附加.test. 例如,com.example.myapp.free构建变体的测试 APK 具有应用程序 ID com.example.myapp.free.test

虽然这不是必需的,但您可以通过在or块中定义testApplicationId属性来更改应用程序 ID。defaultConfigproductFlavor

为了测试这一点,我使用 Android Studio 4.0.1 创建了一个全新的 Android 应用程序。这是完整的build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "ch.dbrgn.myapplication"
        testApplicationId "ch.dbrgn.myapplication.test"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:rules:1.1.1'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

如您所见,我明确设置testApplicationIdch.dbrgn.myapplication.test.

为了测试它是否正常工作,我创建了一个仪器测试:

package ch.dbrgn.myapplication;

import android.content.Context;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertEquals;

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void packageName() {
        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
        assertEquals("ch.dbrgn.myapplication", appContext.getPackageName());
    }

    @Test
    public void applicationId() {
        assertEquals("ch.dbrgn.myapplication.test", BuildConfig.APPLICATION_ID);
    }
}

包不应该有.test后缀,但应用程序 ID 应该。

但是,此测试失败:

ch.dbrgn.myapplication.ExampleInstrumentedTest > applicationId[MI 6 - 10] FAILED
    org.junit.ComparisonFailure: expected:<....dbrgn.myapplication[.test]> but was:<....dbrgn.myapplication[]>
    at org.junit.Assert.assertEquals(Assert.java:115)

如何确保我的仪器测试在具有自己完全独立数据的单独应用程序中运行?

标签: android

解决方案


因此,从这个答案中,您可以看到实际上在进行仪器测试时,安装了 2 个应用程序,一个进行仪器测试,然后是您的应用程序正在测试中。这testApplicationId不是指被测应用程序的应用程序 ID,而是指执行检测的应用程序的应用程序 ID。(如果您想访问它,则必须使用,但这对您没有帮助)。ch.dbrgn.myapplication.test.BuildConfig.APPLICATION_ID

因此,要在进行仪器测试时为被测应用程序提供单独的应用程序 ID,您必须手动定义一个额外的 buildType 并applicationId在那里指定另一个,然后将其用于测试。例如:

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        releaseUnderTest {
            initWith buildTypes.release
            applicationId "ch.dbrgn.myapplication.undertest"
        }
    }

推荐阅读