"Cannot mix test roots with non-test roots"

Viewed 561

I am trying to run instrumented tests for an Android app, but get this compile-time error:

Cannot mix test roots with non-test roots:
    Non-Test Roots: com.my.application.MyApplication
    Test Roots: [com.my.test.ActivityTest]

The application uses a custom app annotated with @HiltAndroidApp, since the docs imply that this is required for Hilt.

My test follows this pattern:

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
class MyTest {
  @Rule
  public HiltAndroidRule hiltRule = new HiltAndroidRule(this);

  @Inject
  SomeStuff stuff;

  @Before
  public void setUp() {
    hiltRule.inject();
  }

The app runner is creating a normal Hilt app:

public class MyAppRunner extends AndroidJUnitRunner {

  @Override
  public Application newApplication(ClassLoader cl, String className, Context context)
      throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return super.newApplication(
            cl, HiltTestApplication.class.getName(), context);

When running a test, I get the compile-time error outlined above. I suppose that the reference to MyApplication comes from the app's AndroidManifest.xml file.

I tried using a @CustomTestApplication with MyApplication, but custom test applications apparently don't work with applications annotated with @HiltAndroidApp.

What is the proper way to set up a test with a Hilt-based application?

1 Answers

To use the Hilt test application in instrumented tests, you need to configure a new test runner. This makes Hilt work for all of the instrumented tests in your project. Perform the following steps:

  1. Create a custom class that extends AndroidJUnitRunner in the androidTest folder.

  2. Override the newApplication function and pass in the name of the generated Hilt test application.

    class CustomTest : AndroidJUnitRunner() {

     override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
         return super.newApplication(cl, HiltTestApplication::class.java.name, context)
     }
    

    }

Next, configure this test runner in your Gradle file as described in the instrumented unit test guide. Make sure you use the full classpath:

android {
    defaultConfig {
        // Replace com.example.android.dagger with your class path.
        testInstrumentationRunner "com.example.android.dagger.CustomTestRunner"
    }
}

Source : https://developer.android.com/training/dependency-injection/hilt-testing

Related