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']
}
}
Related
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.
I've been trying to get the code coverage for my local unit tests and haven't been successful.
Here's a reference on what I mean by local unit tests.
https://developer.android.com/training/testing/unit-testing/local-unit-tests.html
To run my unit tests, I use the following gradle command.
./gradlew clean testDebugUnitTest
This task will run the unit tests but when I view the jacoco file that gets generated (testDebugUnitTest.ec) in "build/jacoco" folder, it always shows an empty coverage.
I've enabled the coverage in my build.gradle file as follows.
android {
buildTypes {
debug {
testCoverageEnabled true
}
}
}
but that doesn't seem to help. Is there something that I am missing?
Note that if I run the local unit tests through Android Studio, everything works fine. I clicked on my "tests" module and click on "Run tests with coverage".
So, I found out the answer to my own question. Oddly enough, it looks like running "testDebugUnitTest" with the "testCoverageEnabled" flag set is the correct way to do it.
However, since apparently gradle's jacoco version is different than the jacoco version that is running in Android Studio and my CI system (Jenkins), it wasn't able to be viewed due to some backwards compatibility issue in jacoco.
To fix the issue, I set my jacoco version in gradle to the same one in my Android Studio (Intellij) and Jenkins.
jacoco {
toolVersion = '0.7.0.201403182114'
}
I put the code above in my build.gradle file.
I've had to solve the problem myself and I was actually expecting the default gradle plugin will have support for code coverage for local unit tests. Unfortunately, out of the box, there is no support for this, even on android gradle plugin version 3.0.1.
Fortunately, however, there is a simple third-party plugin we can use to generate jacoco test reports: gradle-android-junit-jacoco-plugin
To use it, you need to register this plugin's repository and classpath into your root-level build.gradle. Your build.gradle file might look different, but this is what worked for me:
buildscript {
repositories {
// ... there may be other repositories here
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
// ... other classpaths here too
classpath "gradle.plugin.com.vanniktech:gradle-android-junit-jacoco-plugin:0.11.0"
}
}
And to generate the report, one can simply do this:
./gradlew jacocoTestReportDebug
The output will be in one of your modules build folder, for example:
your-module/build/reports/coverage/debug/index.html
Note I verified this working on android gradle plugin 3.0.1.
For reference, my source is this answer from Niklas, creator of the plug-in: https://stackoverflow.com/a/33064500/390718
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.
I have read around, there are a number of extensive answers (like this one) but the Android world evolves so fast that they seem to be a bit outdated and the official documentation still refers to Eclipse with ADT.
I am running AS 1.1 and I am trying to setup simple junit tests to run on the emulator, without Robolectric. If I don't include junit in my build.gradle, it can't find #After, #Before and #Test and I get package org.junit does not exist. Upon adding
// unit tests
androidTestCompile 'junit:junit:4.11'
the error becomes
Error:duplicate files during packaging of APK
[...]/app/build/outputs/apk/app-debug-test-unaligned.apk
Path in archive: LICENSE.txt
Origin 1: [...]/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar
Origin 2: [...]/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar
You can ignore those files in your build.gradle:
android {
packagingOptions {
exclude 'LICENSE.txt'
}
}
Following the console suggestion of excluding LICENSE.txt, it then works but it feels like a hack. So I'm wondering, am I maybe missing something? Thanks.
Android Studio unit testing support comes in 1.1 Beta 4 (release announcement) with Gradle plugin version 1.1.0-rc1.
More info in official document.
However it is experimental feature for now. E.g. it breaks installDebug gradle task.
For using JUnit in instrumentation tests there is good guide for Espresso library and another covering new AndroidJUnitRunner.
If it's any use I set up a boiler plate project allowing the use of Unit tests and Espresso tests by the use of switching build variants. You won't need the use of any third party plugins with this.
https://github.com/hitherejoe/Android-Boilerplate
i think tests in the instruementTest should relevant to android, so need i add an addtional source folder such as src/test/java?
it looking that the testfile in src/test/java didn't compiled.
how can i run a junit test independently?
how can i run the junit test only in a command line, no the instrumentTest about android?
or
put and junit test in the instruementTest folder and call
./gradlew connectedInstrumentTest
but,the unit test won't run at all.
I think this is not possible if you only have the Android plugin in your build.gradle. The only testing that is supported in the Android plugin is in the InstrumentTest folder. The normal test folder is only used by other plugins.
Next to that there is probably support needed in Android Studio itself. But not sure about that.
First, You should built appropriate folder structure in order to match default structure that Gradle is expecting. In Your gradle.build inside android{} section You should add:
sourceSets {
instrumentTest.setRoot('src/instrumentTest')
}
then You should create appropriate folder structure in your src/ folder. Now You should have main/java/your/package/name/YourActivity.java . In order for Gradle to find Your tests You should create structure in src/ folder to mirror Your main structure, like: instrumentTest/java/your/package/name/YourActivityTest.java
next, for Gradle to compile your dependencies You should add in Your gradle.build:
dependencies {
instrumentTestCompile 'com.jayway.android.robotium:robotium-solo:4.2'
instrumentTestCompile 'junit:junit:4.10'
}
Remember, that those are dependencies outside Your buildscript{} section. After You apply those changes You should be able to run Your JUnit tests as well as Robotium tests. Do not forget to hit the 'make' button couple of times for Gradle to catch up.
Right click on the test file in the Project view. Choose Run ...
Don't forget, the directories structures for tests and tested classes must fit. Yours seem dubiously. Here is how to do it easily.