My Android instrumentation tests need to modify / clear application data, therefore I want them to use a separate applicationId so that things like the private data directory and shared preferences are separated.
In the Android documentation, I read the following:
By default, the build tools apply an application ID to your instrumentation test APK using the application ID for the given build variant, appended with
.test. For example, a test APK for thecom.example.myapp.freebuild variant has the application IDcom.example.myapp.free.test.Although it shouldn't be necessary, you can change the application ID by defining the
testApplicationIdproperty in yourdefaultConfigorproductFlavorblock.
To test this, I created a fresh Android app using Android Studio 4.0.1. Here is the complete 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'
}
As you can see, I explicitly set testApplicationId to ch.dbrgn.myapplication.test.
To test that this works properly, I created an instrumentation 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);
}
}
The package should not have the .test suffix, but the application ID should.
However, this test fails:
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)
How can I ensure that my instrumentation tests run in a separate app with its own completely separate data?