I've a shared test folder configured like this in my gradle file:
androidTest {
java.srcDirs += "src/sharedTest/java"
}
test {
java.srcDirs += "src/sharedTest/java"
}
However, at startup I'm getting this error from Android Studio:
Duplicate content roots detected
Path [/Users/fil/Documents/projects/deploy/app/build/generated/source/r/debug] of module [deploy.app.unitTest] was removed from modules
Any idea on how to fix the issue? I've found that I might use test fixtures but I've not found a practical guide to follow :(
This is an issue and you can follow its status here: https://issuetracker.google.com/issues/220326930
As to fix this, you might:
Revert the Android Gradle plugin back to version: 7.1.3
Or refer to the latest comment on this topic:
https://issuetracker.google.com/issues/232007221
A fix for this issue is now available in:
Android Studio Dolphin Beta 2 (2021.3.1.11)
Android Gradle Plugin 7.3.0-beta02
Update: I was able to make it work using the suggestion and the example project I found here: Shared srcDirs between test and androidTest, unresolved references after upgrade to Android Studio Chipmunk (IntelliJ 2021.2.1)
The most difficult parts where:
match correctly productFlavors. Otherwise everything won't work correctly
I'm still importing shared tests from shared folder in order to launch them with the unit test suite (they are robolectric tests so I want also to launch them visually in case of need). Like this:
test {
java.srcDirs += "../shared/src/test/java"
}
put the correct testInstrumentationRunner also in the shared gradle since it was a custom one
import all the shared code in the main package even if it's used in tests (beside actual tests that are in the test folder)
I've updated gradle plugin to 7.2.2 only and I didn't update Android Studio to beta versions to make it work.
Related
I'm configuring an Android multi-module Gradle project that uses Kotlin for both the app AND the Gradle build files (gradle.build.kts).
I'm using Gradle 7.3.3.
First I add the Jacoco plugin to the module-level build.gradle.kts:
...
plugins {
...
jacoco
}
...
Then I click the icon in Android Studio to "sync project with gradle files."
Next, I find the debug build type and add this:
isTestCoverageEnabled = true
When I subsequently run ./gradlew testDebugUnitTest, a file is generated in the module at <MODULE>/build/outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec.
If, however, I don't add the line isTestCoverageEnabled = true, or if I set isTestCoverageEnabled = false, a coverage results file is generated in the module at <MODULE>/build/jacoco/testDebugUnitTest.exec.
When I generate each .exec file's HTML report, the "Total" rows at the bottom have matching counts.
Are these two files equivalent, but just located in different directories depending on the value of isTestCoverageEnabled?
If so, it seems that, as long as jacoco is included in the plugins, coverage results are generated regardless of whether the isTestCoverageEnabled = true line is added. Does isTestCoverageEnabled do anything else besides change the output directory? What am I missing?
I have struggled with this issue for 3 years across multiple projects, but I have a solution (or rather someone who resolved my issues).
The Android-Root-Coverage-Plugin can be used to combine both jUnit and instrumented tests in a Java and/or Kotlin multi module project without any great need to configure anything else. It resolved my following issues:
Getting coverage in multi module project
Incorrect coverage in Kotlin
Combining both jUnit & Instrumented test coverage
It has been confirmed that the cause of my issues were due to a bug in the android gradle plugin and as of Aug, 2022 it has yet to be resolved.
Specific to your question, isTestCoverageEnabled is used to configure the embedded JaCoCo in the android gradle plugin, which as stated above, is known to be buggy. Using the JaCoCo plugin can be configured in the gradle file but does not utilise the embedded JaCoCo in AGP
After updating Android Studio to Chipmunk we can't start our UI tests located in differen folder than androidTest from AndroidStudio itself anymore.
We get instead an error message:
Error running "...Test"
Class "..." not found in module 'OurApp:app'
As mentioned above our tests are not located in androidTest folder, but in sharedTestDebug instead. However it wasn't a problem with prior versions of Android Studio until Chipmunk.
We also add this folders in our build.gradle
sourceSets {
String sharedTestDebugDir = 'src/sharedTestDebug/java'
String sharedTestDir = 'src/sharedTest/java'
androidTest {
java.srcDirs += sharedTestDir
java.srcDirs += sharedTestDebugDir
}
}
Another finding: we are only not able to start single tests. if we start running all tests from AS, it works.
update
Also found out that in "Edit configurations" we are not able to select any instrumented test other then from androidTest folder
update2
same behavior in the dolphin and electric eel versions :(
if you want to run a single instrumented tests you need to select module to run the test from. Unfortunately in the selection you can only select the module with corresponding androidTest folder.
update3
It seems to be a known issue :(
https://issuetracker.google.com/issues/228392691
I found a workaround to let run single instrumentation tests again
I created a symbol link referencing from the folder where our tests located to androidTestDebug. For that I ran following command from the src-folder:
ln -s sharedTestDebug androidTestDebug
To have it also in git I called
git ls-files -s ./app/src/androidTestDebug
and then
git add ./app/src/androidTestDebug
Maybe someone else will find another solution.
I am currently in the process of developing an Instant app, for which I have restructured my monolithic app into feature modules.
Everything was up and running till Android Studio canary 3, but after an update to Android Studio Canary 4 my project fails to build with the following error:
A problem was found with the configuration of task ':minimoBase:dataBindingExportBuildInfoDebugAndroidTest'.
> Directory '/Users/nayak.vishal/projectData/minimo_instant_app_project/putica-client-android-
native/minimoBase/build/intermediates/data-binding-info/androidTest/debug'
specified for property 'xmlOutFolder' does not exist.
The following procedure worked as a workaround for this issue:
Execute the following build commands on the gradle command line
1) gradlew clean
2) gradlew :appModule:assembleDebug
here appModule is the name of the app module for building the installable apk
the build is successful and the debug apk generated in the output folder can be installed successfully
3) gradlew :instantAppModule:assembleDebug
here instantAppModule is the name of the instant app module
the build is successful and the instant app apks can be installed and launched via deep link
Once the above command line builds are successful, building via Android Studio Canary 4 also stops throwing the build error.
I got similar error when I turn on data-binding for library module. When I turn it off and move all classes that require data-binding to app module, it works. So I guess there is a problem that DataBinding doesn't work on Library module any more ( Gradle 2.x fine with this).
dataBinding {
enabled = false
}
I am using com.android.tools.build:gradle:3.0.0-alpha5 and Android Studio 3.0 Preview Canary5
UPDATE
Although the original answer worked, I really want to turn on data-binding on my library module, where I implement some base classes using binding technique. I move them back to library module and upgrade kotlin version to the latest one 1.1.3-2. Suddenly it works also. I am not sure which one is the better but both ways work for me.
UPDATE 2
I am using com.android.tools.build:gradle:3.0.0-alpha9 and kotlin 1.1.3-2 at this time and suddenly the problem re-appear.
Now I think the problem doesn't come from Kotlin. My library module turned dataBiding { enabled=true}, but it doesn't have any layout file. I tried to create a fake layout file wrapped by <layout> tag and it works
<?xml version="1.0" encoding="utf-8"?>
<layout>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</layout>
In your gradle.properties file , add the following line
android.enableAapt2=false
Recent versions of AS3.0 switched to using AAPT2 by default.
You can disable AAPT2 in your gradle.propertіes fіle with above mentioned line of code, and continue developing on AS3 canary 4.
This was an issue for me when I had a "base" feature module without any layouts (all my actual layouts are in separate features)
Adding a dummy layout XML file in the base feature (e.g. as base/src/res/layout/dummy.xml) meant the missing directory was created and the app compiled.
(this is using com.android.tools.build:gradle:3.0.0-alpha6)
I've had the same problem, seems like a bug in Canary 4.
For now, as a workaround, I downgraded to Android Studio 3.0.0 Canary 3 (This is an archive of all Android Studio releases) and also downgraded the Android Gradle plugin to 3.0.0-alpha3:
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
...
}
Updated:
Just check the Canary version after update. For that see Android Studio version just above the toolbar (File..Edit..View..line) where name at end like "Canary X".-> X is number like 3,4,5,etc.
For example suppose updated version(X) is 5.
Try to change that classpath in build.gradle(applicationName) to 3.0.0-alpha5 and sync(/Try) again:
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha5'
}
Means that updated version(X):-
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alphaX'
}
I have added a folder for unit testing in my android studio project. The default folder is andoidTest but I have added a new folder and name in test instead. (like robolectric sample tests)
When I add test Dependency in my build.gradle under module such as
testCompile("junit:junit:${junitVersion}")
testCompile ("org.robolectric:robolectric:${robolectricVersion}")
They do not get added to external libraries under project, but when I use the default configuration and use androidTestCompile, it can added external libraries.
Then I thought that maybe I should setRoot for tests in gradle, so I used following in android tag in build.gradle:
sourceSets {
androidTest.setRoot('src/test')
}
But still problem remained. I can run tests using gradlew, but imports in classes in test folder do not apply as well as no external library for test purpose is visible.
Anyone have any solution for this issue?
I was searching and didn't find answer that I thought already covered this. So decided to create new one for the future.
Answer
Android Studio is not picking up unit tests automatically right now. I know it is planned for 1.3 version.
So you have to change test artifact value from Android Instrumental Tests to Unit Tests in Build Variants tool window:
Almost fine your Gradle script but try do that:
sourceSets {
androidTest.setRoot('src/test')
androidTest {
java.srcDirs = ['src/test/java']
}
}
So ultimately I'm trying to separate my integration tests from the unit tests in an Android Studio project. I've found a few resources on the subject:
http://selimober.com/blog/2014/01/24/separate-unit-and-integration-tests-using-gradle/
https://blog.safaribooksonline.com/2013/08/22/gradle-test-organization/
Separating integration tests from unit tests in Android Studio
All these seem to indicate that the way to go is to create a new sourceSet for the integration tests, and then to create a new test task which builds and runs the tests in that source set. I can't get past the first step of creating a source set which is recognized by Android Studio.
Here's what I have within app/build.gradle, which builds without errors, but does not result in an integrationTest source root I can add classes to:
android{
...
sourceSets{
integrationTest {
java.srcDir('src/integrationTest/java')
}
}
}
My questions are:
Where precisely do I have to add the sourceSets block? In build.gradle? in app/build.gradle? In app/build.gradle inside the android block?
Once I've added my source set in he right place using the correct syntax, is this sufficient for Android Studio to detect and present it in the UI along side the main and test sources, or are there additional steps?
edit:
I've attempted to follow the instructions in marius' answer, but integrationTest isn't showing up in my build variants. Here's what I'm seeing:
This is enough:
android{
...
productFlavors{
integrationTest {
}
}
}
Regarding your 1st question: The productFlavors block should be in your app/build.gradle, inside android block.
Regarding your 2nd question: Once you add this to your build.gradle file, you also need to create your folders /src/integrationTest and /src/integrationTest/java . Once that is done, sync your gradle files and choose your new Build Variant from the Build Variant window, in order for the IDE to detect it as the active source folder.