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.free
build variant has the application IDcom.example.myapp.free.test
.Although it shouldn't be necessary, you can change the application ID by defining the
testApplicationId
property in yourdefaultConfig
orproductFlavor
block.
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?