3

I have a Gradle project containing the two modules app and test, where test contains utilities for testing only. Now I'd like to setup this module, so it doesn't include any outputs into the main configuration of app; even not accidentally.

implementation project(':test') # should fail or not contain any inputs

testImplementation project(':test') # should include all inputs
androidTestImplementation project(':test') # should include all inputs

How do I configure test to behave like this?

I'd assume it would be similarly to how the Android plugin handles configurations for build types and flavors, but I'm also not sure on how to figure this out.

I think these are handled with Gradle consumer attributes. Maybe there's a filter or an attribute which could be applied to it to make it only available to tests.

tynn
  • 33,607
  • 8
  • 80
  • 121

3 Answers3

0

You could use annotations for that: https://developer.android.com/studio/write/annotations#visible

Another way would be exclude testing code to new module named as sub_test and use testImplementation or androidTestImplementation of that sub_test module in your test module

Dmytro Batyuk
  • 909
  • 7
  • 15
  • Of course I could do this, but I'm looking for a configuration that helps me to prevent that it accidentally happens. Something similar to how the build variants work. – tynn Aug 21 '19 at 11:55
0

Found: Use separate test modules for instrumented tests, which tells the how to do it:

... apply the com.android.test plugin instead of com.android.library.

Martin Zeitler
  • 49,224
  • 12
  • 97
  • 156
  • Just imagine test fixture, fakes or dummies you implement to be consumed by any given test. It is not about the tests itself. I think I might be looking into _Gradle consumer attributes_. I'll update the question. – tynn Aug 22 '19 at 21:22
  • @tynn the issue is, that unit & instrumentation tests have little in common - therefore it would barely add duplicate code to the project, if you'd add the one kind of tools into the one source-set and the other kind into the other source-set. adding stuff into there which are no tests is perfectly legal; eg. custom `ViewMatcher`. The main problem is still the namespace ...because it builds the test application per module - which somehow defeats your concept. And I can understand the motivation to some degree, but nevertheless the test framework is the imperative. – Martin Zeitler Aug 22 '19 at 21:54
  • The dependencies for the unit or instrumentation are not really my concern. Any other module or artifact would work. I just want to make sure to not leak any dependency module into the main code. Also, on a theoretical side, I'd like to know how to configure Gradle to export a dependencies for test specifically. You already have this for build variants. But why stop there. – tynn Aug 22 '19 at 22:21
0

The java-test-fixtures plugin almost behaves like I wished, just a bit more verbose.

implementation project(':test') # should fail or not contain any inputs

testImplementation testFixtures(project(':test'))
androidTestImplementation testFixtures(project(':test'))

Some other downsides for now

As Tom Tresansky Is the java-test-fixtures plugin incompatible with the Build and run using IntelliJ IDEA setting? asked and answered, the Android Studio doesn't handle the testFixtures source set well.

Also it is not yet available for Kotlin or Android. But as Michael Evans pointed out, there's tasks already open for Android and on YouTrack.

But creating the test fixtures with a Kotlin JVM project and consuming these with an Android project works fine for me.

tynn
  • 33,607
  • 8
  • 80
  • 121