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?
So from this answer, you can see that actually when you are doing instrumentation tests, there are 2 apps being installed, one doing the instrumentation and then your app under test.
This testApplicationId does not refer to the application id of the app under test, but of the app doing the instrumentation. (And if you would want to access that, you would have to use ch.dbrgn.myapplication.test.BuildConfig.APPLICATION_ID, but that won't help you).
So, to have a separate app id for the app under test when doing instrumentation tests, you would have to manually define an extra buildType and specify another applicationId there, and then use that for testing. Eg:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
releaseUnderTest {
initWith buildTypes.release
applicationId "ch.dbrgn.myapplication.undertest"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With