Is it possible to run a single test class using the new Android gradle build framework?
I have a test package that has multiple test classes (All of them are InstrumentationTestCase classes). I've been able to setup my build.gradle file to run the test package
defaultConfig{
testPackageName "com.company.product.tests"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
But is there a way to test only one test case in that package? Otherwise I'll be using the age old adb shell am instrument -w .......
P.S. I don't have time right now to switch to Roboelectric, but I do see that its pretty much the defacto framework nowadays.
Using android.test.InstrumentationTestRunner no, this is not possible. You do, however, have options:
Custom Test Runner
Extend android.test.InstrumentationTestRunner
Add a buildConfigField 'String', 'TEST_NAME', '${testName}', where testName is '"${project.properties.get("test")}"' if set, otherwise null
In your runner, only run tests that match BuildConfig.TEST_NAME (if null, run all tests)
Replace the testInstrumentationRunner with your custom runner
Run tests with ./gradlew connectedCheck -Ptest=com.example.Test.testSomething
Use Spoon
Spoon is an excellent test runner extension that, among other things (like beautiful multi-device test reports), lets you run individual tests. Since you're using gradle, I recommend the Spoon Gradle Plugin, which has an example of exactly what you want to do in its README.
Update: Run Individual Unit Tests with Android Gradle Plugin
With the addition of unit testing support, Android now supports running individul unit tests.
This is just an anchor task, actual test tasks are called testDebug and testRelease etc. If you want to run only some tests, using the gradle --tests flag, you can do it by running ./gradlew testDebug --tests='*.MyTestClass'.
Source
Edit: I should also add that Spoon is a drop-in replacement for running tests. You will not have to modify anything but a few lines in your build script to use it.
As answered in https://stackoverflow.com/a/32603798 there is now
android.testInstrumentationRunnerArguments.class
Related
We have a multi-module Android project, in which some modules contain UI tests and some contain Unit tests. We wish to run all UI tests from all modules using a single Gradle command and do the same thing for Unit tests.
The only way that we found to do this was with the following config inside the main app module that implements all the other sub-modules (basically make the app module know about all the other androidTest and test folders in the project):
app/build.gradle:
sourceSets {
androidTest.java.srcDirs += ["${project(':feature-login').projectDir}/src/androidTest/java"]
test.java.srcDirs += ["${project(':feature-login').projectDir}/src/test/java"]
test.java.srcDirs += ["${project(':core').projectDir}/src/test/java"]
}
Then we run the following Gradle commands:
./gradlew app:connectedDemoDebugAndroidTest
./gradlew app:testDemoDebugUnitTest
Question: Is there a better/simpler way to achieve this? Or is there a way to add the androidTest and test folders from the above solution dynamically (using a relative path), instead of having to write the srcDirs line for each and every module (we have 40+ modules)?
just run in terminal:
./gradlew test
Please, see docs for more options
I do that every day (I usually have a source set for unit tests and one for slower integration tests): ./gradlew check. It runs all test tasks.
From the gradle docs:
check
Depends on: test
Aggregate task that performs verification tasks, such as running the tests. Some plugins add their own verification tasks to check. You should also attach any custom Test tasks to this lifecycle task if you want them to execute for a full build. This task is added by the Base Plugin.
Is anyone aware of a sample project that shows how to get test orchestrator working? I checked the google samples and there doesn't seem to be a good sample project that shows test orchestrator.
https://github.com/googlesamples/android-testing
I have been attempting to get android tests running in the test orchestrator but have been struggling to get it to work correctly. I tried both running the tests through Android Studio (latest 3.2.1) as well as the command line (https://developer.android.com/training/testing/junit-runner#ato-command-line). I used the Android developer document for reference.
https://developer.android.com/training/testing/junit-runner
Here are the steps I followed.
1) Create an empty activity application using the wizard in Android
Studio
2) Enable the test orchestrator using the steps provided here
(https://developer.android.com/training/testing/junit-runner).
3) Run the unit tests from within the IDE and from the command line.
When I do this, I get an error indicating that my "test suite is empty". I get the same error running from command-line.
Note that if I run the test without test orchestrator, then the test runs successfully.
Also note that I am using the latest test orchestrator versions
test-orchestrator (https://maven.google.com/androidx/test/orchestrator/1.1.0/orchestrator-1.1.0.apk)
test-services (https://maven.google.com/androidx/test/services/test-services/1.1.0/test-services-1.1.0.apk)
The complete configuration to run test orchestrator:
Add dependencies:
androidTestImplementation "androidx.test:runner:$testRunner"
androidTestUtil "androidx.test:orchestrator:$testOrchestrator"
Add clear package instruction (within defaultConfig in app's build.gradle):
//allows run all tests on an isolated way. If we need to debug a test, should disable this and the orchestrator
testInstrumentationRunnerArguments clearPackageData: 'true'
Add to testOptions Android/AndroidX orchestrator:
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
I am writing some test cases in my project and I have bunch questions about android unit test with android studio & gradle I met in recent days and cannot get the good answers after searching.
Here are situations I have met and they are really bothering me.
Situation 1:
When I put the test cases in androidTest folder and run graldew cAT and also use the annotation #AndroidJUnit4 for the test class. I can run the unit test and get the right results. But after I just changed the #AndroidJUnit4 to #MockitoJUnitRunner (I need mock the context). The android studio or gradle cannot find any test, only tell "empty suit".
Situation 2:
When I put the test cases in test folder and run graldew test and also use the annotation #MockitoJUnitRunner. It can find the tests successfully. But I guess it only run locally. If the test cases dependent some native lib, it will give the failure message like: java.lang.UnsatisfiedLinkError: no libxx in java.library.path
So here are questions:
Question 1:
It seems that we can put the test code in src/test or src/androidTest. So what are differences between these two folders?
Question 2:
What are differences between gradlew cAT and gradle test? Are these two commands related to folder (test/androidTest folder I mentioned) in projects?
Question 3:
In my situation, I need write some test cases, which dependent the Context and native so. What should I do for that?
As this is actually 3 questions, it might have been best to create 3 separate SO questions. In any event, here are the answers:
Answer 1:
The src/test folder is meant for "regular" JUnit unit tests. These are tests that run in a regular JVM.
The src/androidTest folder is meant for any tests that require an Android device or emulator to be running. This is where your Espresso tests would live.
Answer 2:
The command gradlew cAT or gradlew connectedAndroidTest runs any tests which require a connected device (cAT standing for Connected Android Test) that are in the src/androidTest directory, while the command gradle test runs just unit tests, in src/test directory.
Answer 3:
If your unit tests depend on Context, consider using Robolectric for your unit tests. This will give you access to Context. Good examples for how to use Robolectric can be found in Corey Latislaw's "Android Katas" repo.
EDIT
Situation 1:
I'm not sure if this is what you are experiencing, but when I have run into this "Empty test suite" error (when I clearly have tests in the directory), it was because I forgot to include the Android JUnit Test Instrumentation Runner in my module's build.gradle file. Include it in the defaultConfig section of your android section, like this:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.kiodev.example"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
I'm trying to setup a task that will setup a different runner in the android gradle plugin.
My idea is to have something like:
./gradlew differentRunner connectedAndroidTest
That would run androidTests with a different runner.
What I have so far:
task differentRunner << {
project.android.defaultConfig.testInstrumentationRunner = "com.example.DifferentRunner"
println 'Different runner set.'
}
But, even though I see the log printed when issuing the above mentioned command, tests are run with the runner set in defaultConfig.
How could I achieve this?
P.S. I know I could use flavours, but those are just not an option for me, I would like to setup a custom task.
I understand you don't want to use flavors etc to accomplish this, but if you're flexible on using a custom task then properties may be a viable option.
testInstrumentationRunner project.hasProperty('customRunner') ? 'com.example.DifferentRunner' : 'default runner'
and then to run using custom runner:
./gradlew -PcustomRunner connectedAndroidTest
I am writing junit tests on android project using the new unit test support http://tools.android.com/tech-docs/unit-testing-support.
While the unit tests run on the 'com.android.application' module perfectly but they always fail on the 'com.android.library' modules. This has not been documented in http://tools.android.com/tech-docs/unit-testing-support . So I wonder whether I am the culprit.
When I write those tests on library modules, the tests can not find the classes on the module and always gives following errors:
package does not exist
error: cannot find symbol
The android unit test support is in experimental phase right now, but is there a solution to it.
UPDATE
I have added this issue to android issue tracker https://code.google.com/p/android/issues/detail?id=161038
It looks like the task to compile the unit tests doesn't depend on the task to compile the library code.
The following fixed it for me:
afterEvaluate {
tasks['assembleDebugUnitTest'].dependsOn(tasks['assembleDebug'])
}
I run the tests using
./gradlew testDebug
If you don't want to modify your build.gradle, manually specify the assembleDebug task on the command line should also do the trick:
./gradlew assembleDebug testDebug
In my android library project I also failed to get the tests running. What I did was create a test application that uses the library and wrote tests in the application that call the library methods.
This might not be the ideal solution, but was the way we got this to work.
Have a look over here https://github.com/nenick/AndroidStudioAndRobolectric
There you can run unit tests on libraries and flavors. And no you don't need to use Robolectric as Gaurav Vashisth stated. You can if you want to.
Here is an example of JUnit test in a library module