48

Is there a way to run a specific Android instrumentation unit test using Gradle? I've tried

gradle -Dtest.single=UnitTestName connectedInstrumentTest

but it seems to run all the tests in the package.

tir38
  • 9,810
  • 10
  • 64
  • 107
Ivan Gromov
  • 4,195
  • 9
  • 41
  • 57

8 Answers8

28

Using test.single appears to be deprecated. The new correct way to do this is

./gradlew :<module>:test --tests <pattern>

where <pattern> could be something like:

  • com.example.MyTest to run all test methods in com.example.MyTest
  • *MyTest to match every method in every class whose name ends with MyTest
  • *.MyTest.myMethod to run a specific test method in class MyTest in any package

If you have a multi-project build, make sure to give the module path before the test task; otherwise you'll get a misleading error message when it searches for your test pattern in every subproject.

None of this is documented on the Gradle site anywhere I could find it.

Chris Jones
  • 4,815
  • 6
  • 34
  • 28
  • 2
    Sure it's a module with the java plugin applied? Sure it's not an ancient version of Gradle? – Chris Jones Feb 24 '16 at 19:04
  • Yup, using gradle 2.10 and android gradle plugin 2.0.0-beta2 – jlhonora Feb 24 '16 at 20:46
  • Could you complete your answer with some examples? – voghDev Apr 11 '16 at 10:53
  • My answer already contains examples. Is there something wrong with them? – Chris Jones Apr 12 '16 at 16:15
  • 9
    I get `Unknown command-line option '--tests'` if I do `./gradlew test --tests *MyTest`, but it works fine if I do `./gradlew testStagingDebug --tests *Mytest`. (My project has flavors, so `testStagingDebug` is the task I normally run to execute tests, although the `test` task exists and works.) – kodi Jun 03 '16 at 18:55
  • 3
    You seem to get `Unknown command-line option '--tests'` unless you specify either a wildcard in the pattern OR use ::testDebug (or some other flavor) – aaronvargas Mar 14 '18 at 22:45
  • 3
    Instead of `--tests` I got the following to work `./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.locuslabs.android.sdk.TestActivityTest` thanks to https://stackoverflow.com/a/49403467/2848676 – Michael Osofsky Dec 24 '18 at 18:10
  • 1
    To be clear @ChrisJones' answer is for **local** unit tests. If you want to run **instrumented** (unit) tests you need to use Michael Osofsky answer – tir38 Jan 27 '20 at 20:29
27

This works if you're using an instrumentationTestRunner:

./gradlew test -Pandroid.testInstrumentationRunnerArguments.class=<pkg>.YourClassName

Using gradle 2.10 and android gradle plugin 2.0.0-beta2.

Since you know what test(s) you want to run, you probably know which module / flavor to use too. You can help Gradle out by specifying the exact module and Gradle task. So if your test is in the app module and you want to test the debug flavor:

./gradlew app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=<pkg>.YourClassName

You can get even more fancy with the tests_regex argument instead:

./gradlew app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.tests_regex=PartialClassName*
./gradlew app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.tests_regex=partialMethodName*
tir38
  • 9,810
  • 10
  • 64
  • 107
jlhonora
  • 10,179
  • 10
  • 46
  • 70
  • 2
    This is the only version that actually works for instrumentation tests with the Android Gradle plugin 2.0 and later. The syntax is more then fugly, but yeah... – Thomas Keller Mar 17 '16 at 12:37
  • 4
    This also worked for running a test on connected phone: `./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class='.YourClassName'` – Stan Kurdziel Jul 21 '16 at 17:40
  • 2
    For testing a specific package it is `-Pandroid.testInstrumentationRunnerArguments.package=my.package` – Thomas R. Feb 03 '17 at 14:00
  • I always forget this and have to keep coming back here to look this up. So I wrote a quick shell script that may be helpful to others: https://gist.github.com/tir38/1266cbf745f0077b0bbb8e54bf255f8f – tir38 Apr 29 '19 at 18:31
  • 1
    To run a specific unit test: `./gradlew connectedDevAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.StringUtilTest#testSelectLanguageFragment` To run tests from 2 specific classes (separate with comma): `./gradlew connectedDevAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.StringUtilTest,com.example.OtherTest` – ThomasW Feb 10 '20 at 07:11
21

The pattern is -D<testTaskName>.single=<TestClass> so in your example it should be:

gradle -DconnectedInstrumentTest.single=UnitTestName connectedInstrumentTest

NOTE: This answer is outdated. You should use the --tests switch in the latest versions of Gradle. (see other answers for an explanation)

erdi
  • 6,944
  • 18
  • 28
7

Since Android gradle plugin 1.1.0-rc1, one can run single test class using --tests flag by executing:

./gradlew app:testDebug --tests=com.example.MyTest

See http://tools.android.com/tech-docs/unit-testing-support#TOC-Running-from-Gradle

k4dima
  • 6,070
  • 5
  • 41
  • 39
hidro
  • 12,333
  • 6
  • 53
  • 53
  • reference link change, this should be correct for time being https://developer.android.com/studio/test/command-line – peter_budo Jun 11 '19 at 13:43
1

You gotta check this out.

https://github.com/JCAndKSolutions/android-unit-test

I made an issue in this github repository, and this guy solved my problem and upload to maven, so in my build.gradle file I use this plugin.

Instructions are written in his repository. you can easily follow it.

After using this android-unit-test plugin, I can use like

../gradlew -Dtest.single=SomeTest test 

or

../gradlew -Dtest.single=SomeTest clean check

Now it's working and I could only run the specific tests I want to

Wooseong Kim
  • 1,871
  • 2
  • 21
  • 19
1

You should not forget to specify a build variant name after test property declaration like

-Dtest<buildVariantName>=<yourTestName>.

Like if you have a debug build type which gives you debug variant after compilation, then if you want to run a test only for this build variant you should declare a command like this:

./gradlew -DtestDebug=UnitTestName testDebug

Alex Bonel
  • 1,344
  • 1
  • 9
  • 22
0

Erdi's answer didn't work for me but I have a single parent for all my test classes so I was able to do this:

public abstract class BaseEspressoTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
    //...
    @Override
    protected void runTest() throws Throwable {
        if(getClass().getSimpleName().equals("MyTestClassName")) {
            super.runTest();
        }
    }
    //...
}

This executes only MyTestClassName. We can extend it further to execute only specific test method (or methods):

public abstract class BaseEspressoTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
    //...
    @Override
    protected void runTest() throws Throwable {
        if("MyTestClassName".equals(getClass().getSimpleName()) 
           && "testMethodName".equals(getName())) {
            super.runTest();
        }
    }
    //...
}
0

the Gradle command does not work for me. I used below mentioened adb command. for this you need to build your apk first.

adb shell am instrument -w -r -e package -e debug false .debug.test/android.support.test.runner.AndroidJUnitRunner

Tarkik
  • 178
  • 1
  • 11