14

I want to understand more about ConnectedAndroidTest Gradle task. I see that it is used to install the application and test apks and run the tests.

But what are the individual steps that it does? (gradle tasks if any)

"gradle build" seems to generate the Application apk. What task generates the test apk? And how does it(ConnectedAndroidTest) install the application and test apk? And how does it start the tests?

Thanks very much.

Ahmed Alnabhan
  • 608
  • 1
  • 9
  • 13
ap1234
  • 489
  • 2
  • 6
  • 15

3 Answers3

26

My first SO answer, please be gentle ;)

But what are the individual steps that it does? (gradle tasks if any)

So if you want a high-level overview of what tasks ConnectedAndroidTest depends on, just running ./gradlew connectedAndroidTest or ./gradlew cAT (without the -q option) will output the name of each task that cAT depends on before it itself is executed. The task itself can't have other tasks inside it, but can depend on others coming before it.

From this answer, the gradle build task is actually something java related, and isn't what's responsible for building the test apk. Instead, it's the assembleAndroidTest task that comes right before connectedAndroidTest that does it. You are right about the connectedAndroidTest though, it actually installs and runs the test apk. But I'll come to how in a bit. The rest of my answer is goes into more detail than is necessary to use the task effectively, but is useful if you want to understand how it works.

Some background
Like many other Android gradle plug-in tasks, connectedAndroidTest is actually put together at some point in the execution phase because of the different build variants (debug, release, flavour 1, flavor 2 etc.). So connectedAndroidTest isn't available to you in the configuration phase (when most of your build script logic is executed). Instead, once it's built, it's set as the connectedInstrumentTest property (basically, a field) of the testVariants property in the android object.

As an example for clarification, if you want to access this task to manipulate it somehow (maybe add an Action to the end of it), you can do something like this in your build.gradle file:

android {
  testVariants.all { variant ->
    variant.connectedInstrumentTest.doLast {
      println "This will be executed right after our connectedInstrumentTest!"
      println "The name of the test type: $connectedInstrumentTest.name"
      println "The type of test $connectedInstrumentTest.class"       
    }
  }
}

And then run ./gradlew -q cAT

So here, I'm adding an action to the end of whatever task has been built and assigned to the connectedInstrumentTest property, which is nested fairly deep in the android object. This task will be likely beconnectedDebugAndroidTest or something similar.

What's the task doing?
Now, from the type property I put in the last println, we can see that the class of the task is actually com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask_Decorated. To be honest, I'm not too sure yet where that _Decorated part comes from, but a google search for the rest of the class name provides us with the source code for the base class of the task.

The main Action of the task is called runTests() and shows you more or less how the task accomplishes what it does. If you follow the source code around a bit, you eventually find that the adb pm install command will be used to install the apk.

Although I couldn't quite find it, I suspect that somewhere else the adb command adb shell am instrument -w com.package.name/android.support.test.runner.AndroidJUnitRunner command is being used to finally drive the tests.

So I hope that wasn't too confusing - I learnt most of this very recently so some things might not be 100%. I would suggest working through the gradle docs, in particular how to create a custom plugin and a custom task, and also check out the Android gradle plug-in tools documentation.

Community
  • 1
  • 1
Dean
  • 727
  • 10
  • 17
  • So does `connectedAndroidTest` actually run `build` and `compile`? – IgorGanapolsky Aug 28 '15 at 18:27
  • 1
    `@IgorGanapolsky, `connectedAndroidTest` depends directly on `assembleDebug` (assembles debug APK) and `assembleDebugAndroidTest` (assembles test APK). Those two tasks compile everything. There are also `installDebug` and `installDebugAndroidTest` tasks, but I'm not clear exactly where they are on the dependency tree. They must happen after the `assemble*` tasks, and before the tests actually run (of course), but I'm not sure exactly where. – AutonomousApps Oct 27 '16 at 20:28
  • 1
    Why does ./gradlew connectedDebugAndroidTest uninstall my app when it's done? This is driving me crazy! – Phlip Nov 15 '19 at 17:24
  • me too @Phlip - did you figure this out? It is breaking my test runs! – dazza5000 Dec 08 '20 at 19:58
  • I used primitive gradlew commands to test without uninstalling. they are a pain to run because they expose more than the usual amount of bugs in adb, but I wrote them up here: https://stackoverflow.com/questions/57433975/gradlew-test-connectedandroidtest-erases-my-getfilesdir-folder/60174578#60174578 – Phlip Dec 09 '20 at 21:56
2

To answer the more general question "what are the list of tasks that task <taskName> executes?", there are two simple ways to find that out for any given task.

The first is:

./gradlew tasks --all | grep <taskName> 

where <taskName> should be replaced with whatever task you care about. E.g., ./gradlew tasks --all | grep connectedDebugAndroidTest. Note that I'm piping through grep to save myself the trouble of manually sifting through the list of all tasks.

The second is:

Use the task-tree plugin. Once applied, usage looks like this:

./gradlew <taskName> taskTree

Or, as I usually prefer it:

./gradlew <taskName> taskTree --no-repeat -quiet

The latter option makes the output a bit less cluttered.

AutonomousApps
  • 4,229
  • 4
  • 32
  • 42
1

You could also execute ./gradlew connectedAndroidTest --dry-run which will list all the tasks it'd run, but won't run any. --dry-run does the same for any gradle task that you want to analyze.

César Muñoz
  • 535
  • 1
  • 6
  • 10