40

I just upgraded from Bumblebee to Chipmunk, and I am having multiple dependency-resolution issues in my instrumented androidTests.

These are what my source sets look like:

sourceSets {
    test.java.srcDirs += 'src/testShared/kotlin'
    test.resources.srcDirs += 'src/testShared/resources'
    androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
    androidTest.java.srcDirs += 'src/testShared/kotlin'
    androidTest.resources.srcDirs += 'src/testShared/resources'
}

The idea is to share test data between unit tests and instrumented tests. Keep in mind, the tests can build and execute, but the dependencies show up as red in the IDE. Also, it may not be related, but string resources I reference (that are in a resource module) are also red in the IDE.

Also, when I comment out either the unit test sourceSets that point to testShared, the IDE errors dissapear in my AndroidTests

This was not an issue in the previous version of Android Studio. I think the issue is related to the base IntelliJ IDE platform. Does anyone have any ideas how to fix this issue, or have any workarounds?

Edit: Here is a basic sample project that demonstrates the issue, when running in Chipmunk and above. In bumblebee, there are no unresolved reference errors in androidTest. Also, you may have to tweak the AGP version, as I built this project using Dolphin beta01, but the issue is the same in Chipmunk https://drive.google.com/file/d/1ZCcEwuqM-m4E5qe94vCn52yWMON8rd5P/view?usp=sharing

Sean Blahovici
  • 5,350
  • 4
  • 28
  • 38
  • Can you share a sample project to investigate? – Andrey May 13 '22 at 08:17
  • @Andrey Just linked a basic sample project. Thanks for any help provided! – Sean Blahovici May 14 '22 at 14:17
  • 1
    Thank you! Yes, this looks like a bug in the Android model. Because for ordinary Gradle projects, it works. I think it makes sense to file issue to file a but in Android Studio issue tracker:https://developer.android.com/studio/report-bugs – Andrey May 18 '22 at 13:53
  • Can you link the issue if you opened one with Google? I found that the issue comes from IntelliJ 2021.2 which Chipmunk is based on. The issue isn't resolved in IntelliJ 2021.3 which is Dolphin based on so until then best thing to do is to stay on Bumblebee until Electric Eel is stable enough. – Chapz May 24 '22 at 15:29
  • @Chapz Linked the issue and updated my answer – Sean Blahovici May 29 '22 at 17:49

2 Answers2

17

Looks like this feature is no longer supported in new iterations of the Android Studio IDE and IntelliJ platforms.

Edit: Sharing code this way no longer works. BUT, there is another method to make it work:

Basically, create an android library (sharedTestCode), depend on it in your app via testImplementation and androidTestImplementation. In the sharedTestCode build.gradle file, depend on the app. You should now be able to create shared test data and reference them in both types of tests.

Here is a sample project with this setup working:

https://drive.google.com/file/d/1I2CZhTxHGRgCN9UCEjIuWUfFnGxTF_Cv/view?usp=sharing

Second edit: Make sure that any module that depends on the :app project also defines productFlavors and flavorDimensions, matching the build.gradle configuration of the app's build.gradle file.

So for example, I had to add this code to my sharedTestModule's build.gradle file:

flavorDimensions "environment"

productFlavors {
    local {
        dimension "environment"
    }
    gae {
        dimension "environment"
    }
}

Previous response:

I created a support thread: https://issuetracker.google.com/issues/232420188

and here is the answer from Google about this old way of referencing test data:

Sharing code in this way is not longer supported in the IDE. The reason this was working before is that in pre-chipmunk we ran Android studio import with the intellij options set to create a single module per Gradle project. This option has been removed from IDEA for a good number of years. Importing this way comes with a lot of issues due to the fact that intellij modules can only be set up with two scopes for dependencies and other information, these are compile and test. By default Android modules effectively have three different scopes (which roughly correspond to Gradle source sets per variant) main, unitTest and androidTest. The mapping of these to intellij modules with this option require us to merge the dependencies of unitTest and androidTest. Also any custom source set's need to be merged as well. This caused a lot of incorrect symbol resolution within the editors along with a host of other issues.

In chipmunk we switch to creating a module per (roughly) Gradle source set. This allows us to map the information correctly but unfortunately does result in sharing information between source sets such as this becoming unsupported by the IDE.

To summarize, in order to be correct each source file must only be present in one module otherwise the IDE has no way of knowing which context to use. This can also sometimes result in subtle issues with build. To share sources between test modules you should be able to use put the code in a separate project and consume it as a dependency with both testImplementation and androidTestImplementation.

Sean Blahovici
  • 5,350
  • 4
  • 28
  • 38
  • 2
    excellent... I've no clue to resolve the main app's classes, your assist by declaring the same flavors help me a lot, thank you – Agi Maulana Jun 23 '22 at 10:27
  • to anyone who won't declare the dependencies twice, you can share the library by using `api` instead of `implementation`, the `api` can be declared either in the main app module or in the shared test module and also declare the repository sources in the shared test module – Agi Maulana Jun 23 '22 at 10:37
  • @AgiMaulana what's the difference between implementation and API? – AndroidDev123 Sep 12 '22 at 18:36
  • Where do you write the test inside the `sharedTest` module? do you write in directly in `src/main/java` or do we write it in either `src/test/java`/`src/androidTest/java`? – Archie G. Quiñones Sep 19 '22 at 09:24
  • @ArchieG.Quiñones you do not write any tests in that module. The goal of the module is to have shared test data, to avoid duplication between integration and unit tests. But the itself is in the src/main/java folder. – Sean Blahovici Sep 19 '22 at 13:51
  • 2
    That is insane. I have two classes that I want to share, this requires creating a full library??? – MidasLefko May 08 '23 at 10:44
5

To solve this, move your shared test dependencies into a separate module. Here's how:

  • Right click in the project window and go to New -> Module
  • Choose the "Android library" template
  • Module name shared-test
  • Package name should be whatever it is in your main app
  • Click "Finish"

enter image description here

Move your shared code inside the :shared-test module.

Now, in your app's build.gradle file add a dependency on the :shared-test module for the unit and instrumented test build configurations:

testImplementation(project(":shared-test"))
androidTestImplementation(project(":shared-test"))

If your shared test code is dependent on code in your app (for example, you have Hilt modules which reference app interfaces), add a dependency in your shared-test module's build.gradle file on the app module:

implementation(project(":app"))

Example on GitHub here: https://github.com/android/architecture-samples

donturner
  • 17,867
  • 8
  • 59
  • 81