Status Update
Comments
ar...@gmail.com <ar...@gmail.com> #2
uc...@google.com <uc...@google.com> #3
je...@google.com <je...@google.com>
tr...@gmail.com <tr...@gmail.com> #4
my project has it working with jar modules although studio doesn't handle the srcSet correctly yet. Here is the issue I created for that case.
I would love to see something equivalent to "java-test-fixtures" for android projects. perhaps as an additional jar within the aar format or as a standalone jar that is published seperately making use of gradle .module metadata to automagically hook things up for the consumer?
[Deleted User] <[Deleted User]> #5
tr...@gmail.com <tr...@gmail.com> #6
This issues seems to me about using the `java-test-fixtures` plugin on a project that based on the `com.android.library` plugin.
ro...@miquido.com <ro...@miquido.com> #7
Any progress or plans to support testFixtures for android libraries?
[Deleted User] <[Deleted User]> #8
any equivalent/alternative approach for test fixtures / sharedTest best practice on android?
st...@gmail.com <st...@gmail.com> #9
This module can depend on other modules via the `implementation` configuration while the other modules can be used this `test-fixtures` via the `testImplementation` configuration.
And no, this will not lead to a circular dependency :). Gradle is smart enough to handle this for you.
eu...@gmail.com <eu...@gmail.com> #10
I guess a "common pattern" is to create a
test-fixtures
Gradle module and create the test fixtures in this module. This module can depend on other modules via theimplementation
configuration while the other modules can be used thistest-fixtures
via thetestImplementation
configuration. And no, this will not lead to a circular dependency :). Gradle is smart enough to handle this for you.
Just want to add a visualization of the idea. See the attachment or here -
ma...@gmail.com <ma...@gmail.com> #11
st...@gmail.com <st...@gmail.com> #12
What I meant is not to create a new module for each but rather create one module for all of your test fixtures.
ma...@gmail.com <ma...@gmail.com> #13
ta...@gmail.com <ta...@gmail.com> #14
We've been doing this but it is truly a workaround. The problem is that the classes will be seen as production code in the IDE. These are test code and they will also be seen as untested code in the test coverage report.
pa...@gmail.com <pa...@gmail.com> #15
We use this workaround, and while there have been some "fun" moments during AGP upgrades, it's quite stable and non-invasive solution:
// gradle/export-test-helpers.gradle
/*
* Creates a new configuration and publishes a test utility JAR so you can depend on it from other modules.
* For example:
* testImplementation project(path: ':feature:other-module', configuration: 'test-helpers')
*
* To export test-helpers JAR from any com.android.library module, add to its build.gradle:
* apply from: rootProject.file('gradle/export-test-helpers.gradle')
*/
task jarTestHelpers(type: Jar, dependsOn: 'assembleDebugUnitTest') {
from "$buildDir/intermediates/javac/debugUnitTest/classes"
from "$buildDir/tmp/kotlin-classes/debugUnitTest"
// exclude classes ending in 'Test' or 'TestKt' and any inner or anonymous classes
exclude '**/*Test.class'
exclude '**/*TestKt.class'
exclude '**/*Test_*.class'
exclude '**/*Test$*.class'
exclude '**/*TestKt$*.class'
// as of AGP 3.4+ R classes are generated within intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes
// when using android.testOptions.unitTests.includeAndroidResources = true, this causes conflicts with merging of resources
// the ids in these R files are different to those in the app/androidTest apk
exclude '**/R.class'
exclude '**/R$*.class'
includeEmptyDirs false
classifier = 'test-helpers'
}
configurations {
maybeCreate 'test-helpers'
}
artifacts {
add 'test-helpers', jarTestHelpers
}
One downside: it's not aware of flavors/build types/variants, so it'll always use the debug classes. This could probably be alleviated with some loops on libraryVariants and a utility function for adding all the right dependencies to the right configurations.
ma...@gmail.com <ma...@gmail.com> #16
[Deleted User] <[Deleted User]> #17
Thanks for this samples:
The workaround for build variants support, might a little bit tedious to store it on environment variable, thus the above code modified into this:
def buildVariant = System.getenv("BUILD_VARIANT_ENV") // beware of null env variable, might need to fallback to default env instead
debugUnitTest -> ${buildVariant}UnitTest
it's good when running on CI, but when development, the hardest part is changing env variable every time we want test another build variant
pa...@gmail.com <pa...@gmail.com> #18
#17 You could try looking at using one of these
[Deleted User] <[Deleted User]> #19
I also was wondering how to achieve this, so thanks for the script.
I updated it to support multiple flavors, feel free to improve it:
```
configurations {
maybeCreate 'test-helpers'
}
android.libraryVariants.all { variant ->
if (
def flavorName = variant.flavorName
def capitalizedFlavorName = flavorName.capitalize()
def customTask = task ("${flavorName}JarTestHelpers", type: Jar, dependsOn: "assemble${capitalizedFlavorName}DebugUnitTest") {
from "$buildDir/intermediates/javac/${flavorName}DebugUnitTest/classes"
from "$buildDir/tmp/kotlin-classes/${flavorName}DebugUnitTest"
// exclude classes ending in 'Test' or 'TestKt' and any inner or anonymous classes
exclude '**/*Test.class'
exclude '**/*TestKt.class'
exclude '**/*Test_*.class'
exclude '**/*Test$*.class'
exclude '**/*TestKt$*.class'
// As of AGP 3.4+ R classes are generated within intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes
// when using android.testOptions.unitTests.includeAndroidResources = true, this causes conflicts with merging of resources
// the ids in these R files are different to those in the app/androidTest apk
exclude '**/R.class'
exclude '**/R$*.class'
includeEmptyDirs false
group = "test helpers"
archiveFileName.set("${flavorName}_test_helpers.jar")
archiveClassifier.set('test-helpers')
}
artifacts {
add 'test-helpers', customTask
}
}
}
```
l....@gmail.com <l....@gmail.com> #20
Hate to be that guy, but is there an update after having this ticket on P1 for over a year now? Testing story on Android is far from ideal as it is, and this feature would certainly help.
os...@gmail.com <os...@gmail.com> #21
I have just run into this problem with my team as we move towards testing more and more of our app, and its unfortunate we have had to a workaround for this. Testing on Android is messy and complex, and this would certainly go a long way to making our setup less messy and complex.
zt...@gmail.com <zt...@gmail.com> #22
My understanding is that Kotlin support is lacking for this feature as well
de...@matthewnelson.io <de...@matthewnelson.io> #23
This would alleviate a lot of headaches surrounding multi-module projects and testing.
It would also help in preserving internal visibility modifiers such that devs aren't having to choose between breaking encapsulation just to be able to setup a separate test module, or deploy work-a-rounds with configurations/artifacts.
je...@google.com <je...@google.com>
ku...@gmail.com <ku...@gmail.com> #24
Is this issue tracking the work for supporting testFixtures for emulator tests, JVM tests, or both?
Would love to have support for both JVM and instrumentation tests.
am...@google.com <am...@google.com> #25
Both unit tests and instrumentation tests should be able to consume the test fixtures, so yes this issue is for both
ju...@gmail.com <ju...@gmail.com> #26
gu...@glovoapp.com <gu...@glovoapp.com> #27
am...@google.com <am...@google.com> #28
The feature is currently incubating for Android projects, the IDE support for both java-test-fixtures
's and the android testFixtures source sets is under development.
If you want to try it out in AGP 7.1 without studio's support, you can add the following to your project's buildscript
android {
testFixtures {
enable true
// enable testFixtures's android resources
// androidResources true
}
}
lo...@gmail.com <lo...@gmail.com> #29
Please, let us know when Android Studio support is ready to be tried in a Canary, I'll be happy to start testing and using it.
ju...@gmail.com <ju...@gmail.com> #30
jo...@gmail.com <jo...@gmail.com> #31
ai...@gmail.com <ai...@gmail.com> #32
Alpha versions of 7.1 are available, the latest one is 7.1.0-alpha12
ge...@gmail.com <ge...@gmail.com> #33
am...@google.com <am...@google.com> #34
Currently the kotlin plugin doesn't support compiling android testFixtures kotlin sources
am...@google.com <am...@google.com> #35
Starting Chipmunk alpha 5 which will be released next week, Android Studio supports both android and java testFixtures.
To enable testFixtures in your android library module, add the following to your build.gradle
file
android {
testFixtures {
enable true
// enable testFixtures's android resources
// androidResources true
}
}
You can then add your testFixtures sources to $projectDir/src/testFixtures/java
and $projectDir/src/testFixtures/res
. By default, the testFixtures will have a dependency on the main sources, while both test and androidTest will have a dependency on the testFixtures sources. To add a specific dependency for the testFixtures you can use the testFixtures
prefix + the configuration type, same as what you would do for test and androidTest
dependencies {
testFixturesApi 'com.google.truth:truth:0.44'
testFixturesImplementation 'com.google.code.gson:gson:2.2.4'
}
To consume the local library's testFixtures in another module, you can use Gradle's helper method testFixtures
same as what you would do for a java library
dependencies {
testImplementation testFixtures(project(":lib"))
}
By default, publishing your library also publishes the testFixtures aar with the main library, Gradle metadata file will contain information for Gradle to be able to consume the right artifact when requesting the testFixtures component.
android {
publishing {
singleVariant("release")
}
}
To disable publishing the testFixtures aar of a library, add the following to your build.gradle
afterEvaluate {
components.release.withVariantsFromConfiguration(
configurations.releaseTestFixturesVariantReleaseApiPublication) { skip() }
components.release.withVariantsFromConfiguration(
configurations.releaseTestFixturesVariantReleaseRuntimePublication) { skip() }
}
Consuming the testFixtures aar of a published android library is the same as java libraries
dependencies {
testImplementation testFixtures('com.example.company:publishedLib:1.0')
}
By default, lint will analyze test fixtures sources. You can configure lint to ignore test fixtures sources as follows:
android {
lint {
ignoreTestFixturesSources true
}
}
Note that currently the kotlin plugin doesn't support compiling the testFixtures kotlin sources.
You can follow the updates on kotlin support on the youtrack issue
Please try out the feature if you can and file a new bug if you encounter any problem with it.
zs...@gmail.com <zs...@gmail.com> #36
ha...@gmail.com <ha...@gmail.com> #37
#36 You'd rather want them to rush experimental features in stable builds?
lo...@gmail.com <lo...@gmail.com> #38
Not the original poster, but I'd rather have just 2 AS channels, IDEA style, where the EAP gets becomes a beta then a release 4 times in a year rather than once a year with never ending compromises between 3 channels.
That way, we'd get new features like testFixtures stabilized within 3 months, even if behind a flag.
lo...@gmail.com <lo...@gmail.com> #39
BTW, the feature was requested over 2 years ago, waiting another year is quite demoralizing as to when the community can fully take advantage of something that's been in the JVM world for a while.
pa...@gmail.com <pa...@gmail.com> #40
Priorities... we're all devs, know how it works. At least this one got to the top, good to see investment in better ways of testing. We should be saying thanks, but it's never enough, isn't it? 😅
So, Thank You! for making it work, whenever it gets released.
Also pretty good quick-start at #35, will that get into release notes of alpha05 and Chipmunk final too?
To prevent flaming: I'm in full support of smaller, more focused releases with a faster cadence as described in #38.
pa...@nearside.com <pa...@nearside.com> #41
(I'm sorry this is slightly off-topic)
AGP is developed entirely in open source, if anyone doesn't like the speed of execution they're welcome to submit a CL, I imagine.
Also, I've been on the Chipmunk canary since Alpha 1, it's remarkably stable (for my workflow), and for the bugs I have found (with previous AS+AGP alpha/betas) the team has been incredibly responsive.
Either join the canaries or accept that the features won't land in prod for ~6-9mo. You can't have it both ways :)
zs...@gmail.com <zs...@gmail.com> #42
understand the difficulties of shipping software, which are further
compounded by shipping software used to ship software. 🙂
Thank you team! Looking forward to using test fixtures.
On Fri, Nov 12, 2021 at 4:12 PM <buganizer-system@google.com> wrote:
eu...@gmail.com <eu...@gmail.com> #43
That setup doesn't work for me.
I have enabled test fixtures -
I run ./gradlew :dat:bundleDebugTestFixturesAar
I see database-debug-testFixtures-testFixtures.aar
output however, it is empty aar file - no classes.
bi...@trendyol.com <bi...@trendyol.com> #44
#43, can you try with .java
class?
eu...@gmail.com <eu...@gmail.com> #45
—
Kind Regards,
Eugen
bi...@gmail.com <bi...@gmail.com> #46
eu...@gmail.com <eu...@gmail.com> #47
I misinterpret the kotlin plugin support notion. That is clear now :)
For the couple of last months I was updating AGP on this test project waiting until I can use test fixtures. And I was always thinking it is not ready. However, it looks like time is close.
Sure kotlin support is the most needed.
sa...@google.com <sa...@google.com> #48
Thank you for your patience while our engineering team worked to resolve this issue. A fix for this issue is now available in:
- Android Studio Chipmunk Canary 6 (2021.2.1.6)
- Android Gradle Plugin 7.2.0-alpha06
We encourage you to try the latest update.
If you notice further issues or have questions, please file a new bug report.
Thank you for taking the time to submit feedback — we really appreciate it!
te...@stash.com <te...@stash.com> #49
Given that Kotlin and lint are not supported in testFixtures are there separate issues tracking their development? Or should we expect updates here?
am...@google.com <am...@google.com> #50
Lint support is already implemented as published on Android Studio Chipmunk preview features
By default, lint will analyze test fixtures sources. You can configure lint to ignore test fixtures sources as follows:
android {
lint {
ignoreTestFixturesSources true
}
}
You can follow the updates on kotlin support on the youtrack issue
eu...@gmail.com <eu...@gmail.com> #51
I have added ticket that is probably duplicate to this
ia...@stan.com.au <ia...@stan.com.au> #52
am...@google.com <am...@google.com> #53
Do you have a testFixturesApi
dependency on these libraries?
ia...@stan.com.au <ia...@stan.com.au> #54
However, I have tried exporting test fixtures from another module that have no dependencies and I have the same issue.
For clarity this is how my app is set up
I have an android library module called presentation. In there i depend on espresso for test fixtures:
`testFixturesApi(Dependencies.Test.Instrumented.Espresso.core)`
and also enabled test fixtures like this:
testFixtures {
enable = true
androidResources = false
}
Then in my main app module i import it like this:
androidTestImplementation(testFixtures(project(":presentation")))
As mentioned everything works, i get code completion and running the tests from android studio works as expected. But not when I use the cli
am...@google.com <am...@google.com> #55
I wasn't able to reproduce the problem locally with a similar setup. Could you file a new bug with a small project that reproduces the issue?
ar...@dicoding.com <ar...@dicoding.com> #56
fa...@gmail.com <fa...@gmail.com> #57
gr...@zimmerbiomet.com <gr...@zimmerbiomet.com> #58
I found that it only works in limited cases. If I define a java library with fixtures I can resolve those to an app. However, if I define an android library with fixtures enabled that depends on that same library it breaks. The IDE resolves imports so that there are no apparent errors but when I try to compile those same fixtures it breaks. The same trying to use fixtures from that Android library in app tests. The IDE resolves the class so there is no apparent error until compile time.
You can see the failures by trying to run any of the included tests in the attached zip.
am...@google.com <am...@google.com> #59
As mentioned before, kotlin support for android testFixtures is still a WIP, you can track the progress on the youtrack issue
gr...@zimmerbiomet.com <gr...@zimmerbiomet.com> #60
Given that Kotlin is a suggested language that many Google features are now written in this is obviously not an acceptable answer. You should not have listed testFixtures as a supported feature in the 7.2.0 AGP release and it should be listed as a caveat in the release notes.
Furthermore, as I pointed out the testFixture written in Kotlin in the java library works just fine in a test using the Android plugin with an application module but not a library module. That inconsistency seems strange to blame on JetBrains.
am...@google.com <am...@google.com> #61
Consuming testFixtures of a java library should work whether it's written in kotlin or java (in both android app and library modules). I've verified that it's working with a dummy project. Can you file a bug with a project reproducing the issue?
za...@faire.com <za...@faire.com> #62
Android Studio Dolphin | 2021.3.1 Build #AI-213.7172.25.2113.9014738, built on August 31, 2022
Android Gradle Plugin 7.3.0
Kotlin 1.7.0
Gradle 7.5
Target SDK 32
You can even update the project from
pa...@gmail.com <pa...@gmail.com> #63
#62 I think you're bugging the wrong ticket. Kotlin support is in Kotlin Gradle Plugin:
za...@faire.com <za...@faire.com> #64
The Base module is an Android library using kotlin
```
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
```
The Base module has test fixtures enabled in it's gradle file
```
testFixtures {
enable = true
}
```
Within the Base module there is a `testFixtures` setup that has a single class `BaseServiceFixture` which is a kotlin file
The `testFixtures` are added as a dependency in both the Base and app modules
```
testImplementation testFixtures(project(":Base"))
```
In both the `BaseServiceTest` and `MainServiceTest` the fixture is imported and no errors are shown
```
import com.example.base.BaseServiceFixture
```
However, when I try to run the test there is an unresolved reference error
```
TextFixturesIssue/app/src/test/java/com/example/textfixturesissue/MainServiceTest.kt: (3, 25): Unresolved reference: BaseServiceFixture
```
jh...@themeetgroup.com <jh...@themeetgroup.com> #65
@
Therefore the only way to fix it is to resolve the Kotlin ticket:
pa...@gmail.com <pa...@gmail.com> #66
Now it's on Google to solve this for Kotlin too. They have plans to make it part of AGP.
Please vote on
@google dupe this?
gr...@zimmerbiomet.com <gr...@zimmerbiomet.com> #67
JetBrains has rejected
am...@google.com <am...@google.com> #68
We've found an issue with the IDE support for consuming testFixtures sourcesets in an android project if the build.gradle
file where you have testFixtures enabled
afterEvaluate {
project.configurations.configureEach {
def testFixturesCapability =
it.getOutgoing().capabilities.find { it.name.endsWith("-test-fixtures") }
if (testFixturesCapability != null) {
it.getOutgoing().capability(
new org.gradle.internal.component.external.model.ImmutableCapability(
testFixturesCapability.group, testFixturesCapability.name, null))
}
}
}
za...@gmail.com <za...@gmail.com> #69
I've tried the above but it doesn't seem to be enough. The IDE does not recognize the src/testFixtures
directory and it does not produce compiled test fixture outputs.
am...@google.com <am...@google.com> #70
for kts you might want to replace find
with outgoing.capabilities.firstOrNull { it.name.endsWith("-test-fixtures") }
za...@gmail.com <za...@gmail.com> #71
There's no difference. That function is equivalent to find()
am...@google.com <am...@google.com> #72
You're right sorry, you can't apply java-test-fixtures
plugin in an android library as it depends on the java plugin android.testFixtures.enable = true
. Note that kotlin plugin support for android testFixtures sources is not available yet.
za...@gmail.com <za...@gmail.com> #73
Got it. Is that support what's coming in 8.0?
am...@google.com <am...@google.com> #74
Unfortunately not, the fix mentioned in
The support for kotlin sources requires non-trivial migration for the whole kotlin gradle plugin away from the Android gradle plugin old variant and dsl APIs. The process of the migration is tracked in
pe...@gmail.com <pe...@gmail.com> #75
Maybe we could also share raw assets from testFixtures
?
Not sure what setting androidResources = true
should do.
For me it currently breaks the build with a "Must provide a folder to export generated class list" message.
The cause for this seems to be a clash with databinding through AGP 7.2.2 (issues reproduces with never 7.* versions also, cannot yet update to 8.+) when I try building the project. Note that there are no layouts in the testFixtures
sourceset.
> Task :library:bundleReleaseAar
> Task :library:extractReleaseTestFixturesAnnotations
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':library:javaPreCompileReleaseTestFixtures'.
> Error while evaluating property 'annotationProcessorClassNames' of task ':library:javaPreCompileReleaseTestFixtures'.
> Failed to calculate the value of task ':library:javaPreCompileReleaseTestFixtures' property 'annotationProcessorClassNames'.
> failure, see logs for details.
Must provide a folder to export generated class list
...
Must provide a folder to export generated class list
at android.databinding.tool.util.L.printMessage(L.java:134)
at android.databinding.tool.util.L.e(L.java:107)
at android.databinding.tool.util.Preconditions.check(Preconditions.java:25)
at android.databinding.tool.CompilerArguments.<init>(CompilerArguments.kt:93)
at android.databinding.tool.CompilerArguments.<init>(CompilerArguments.kt:31)
at com.android.build.gradle.internal.tasks.databinding.DataBindingCompilerArguments.asArguments(DataBindingCompilerArguments.kt:163)
at com.android.build.api.component.impl.AnnotationProcessorImpl$finalListOfClassNames$1.transform(AnnotationProcessorImpl.kt:87)
am...@google.com <am...@google.com> #76
Assets should be supported when you enable androidResources in testFixtures
Please file a new bug with the issue you're facing, it'd be helpful if you can provide a stacktrace or a reproducing project.
am...@google.com <am...@google.com>
je...@google.com <je...@google.com>
mi...@google.com <mi...@google.com> #77
It seems that the original issues described by this bug have been resolved. If there are still other issues, please file a separate bug. If there are still any issues with the java-test-fixtures
plugin, please let me know.
za...@gmail.com <za...@gmail.com> #78
What AGP/studio version?
mi...@google.com <mi...@google.com> #79
All the fixes mentioned previously should be in AGP 8.0 and above. For your previous comment, I believe it is still pending on the issue mentioned in
nu...@gmail.com <nu...@gmail.com> #80
sp...@google.com <sp...@google.com> #81
Re # 80 - Kotlin support for test fixtures is blocked by
si...@gmail.com <si...@gmail.com> #82
AGP 8.5 is now released as stable 🙌
pa...@etnetera.cz <pa...@etnetera.cz> #83
Can someone affirm that AGP 8.5 fixed this?
ai...@gmail.com <ai...@gmail.com> #84
Yes, it works with AGP 8.5, we sill see issues with IDE (IDE warning about usage of internal members in testFixture code, but compilation works fine)
li...@gmail.com <li...@gmail.com> #85
So, the IDE showing warning about internal
entities access from testFixtures
- is it an issue or by design?
sp...@google.com <sp...@google.com> #86
Re: #83 - Yes, there is basic support for Kotlin in testFixtures with AGP 8.5. See
Re: #84 and #85 - That's a bug in the IDE; I've created
za...@scotchnetworks.com <za...@scotchnetworks.com> #87
I was able to get testFixtures working, please check this comment:
Description
• Gradle: 5.6
• AGP: 3.4.2
Gradle 5.6 introduced a fancy way of defining fixtures. Unfortunately it does not work with AGP.
I’ve moved one fixture from src/test/java to src/testFixtures/java and activated the "java-test-fixtures" plugin but the compilation fails with the "Unresolved reference" error.
The same effect can be achieved via including "src/testFixtures/java" into the "test" source set but it does not solve publishing and project-level consumption between modules.