---
title: TestingBot Gradle Plugin for Espresso tests.
description: Upload Android apps and run Espresso tests on TestingBot's real device
  cloud straight from your Gradle build with the TestingBot Gradle plugin.
source_url:
  html: https://testingbot.com/support/integrations/ci-cd/gradle
  md: https://testingbot.com/support/integrations/ci-cd/gradle/index.md
---
# Gradle Plugin

We maintain a [Gradle](https://gradle.org/) plugin that uploads your Android app to [TestingBot Storage](https://testingbot.com/support/app-automate/upload) and runs [Espresso](https://testingbot.com/support/app-automate/espresso) tests on TestingBot's real device cloud, straight from your build, with no `curl` scripts required.

- `testingbotUpload` uploads an APK to TestingBot Storage and returns a reusable `tb://<appkey>` identifier. 
- `testingbotEspresso` uploads your app and instrumented test APK, runs Espresso across one or more devices, waits for the results, downloads a JUnit XML report, and fails the build on test failures. 
- `testingbotDevices` lists the Android devices available on your account. 
- Reads credentials from the DSL, Gradle properties or environment variables, and is configuration-cache compatible with no extra HTTP dependencies on your build classpath. 

The plugin is published on the [Gradle Plugin Portal](https://plugins.gradle.org/plugin/com.testingbot.gradle) and the source is available on [GitHub](https://github.com/testingbot/testingbot-gradle-plugin).

## Requirements

- Gradle 8.0 or newer, running on JDK 17 or newer.
- A TestingBot account. Grab your **key** and **secret** from the [member area](https://testingbot.com/members/user/api).

## 1. Installation

Apply the plugin in your Android app module's build file.

    // build.gradle.kts
    plugins {
        id("com.testingbot.gradle") version "0.1.0"
    }

Using the Groovy DSL:

    // build.gradle
    plugins {
        id 'com.testingbot.gradle' version '0.1.0'
    }

## 2. Credentials

Credentials are resolved in this order, first match wins:

- The DSL: `testingbot { key.set("…"); secret.set("…") }`
- Gradle properties: `-Ptestingbot.key=… -Ptestingbot.secret=…` (or in `gradle.properties`)
- Environment variables: `TESTINGBOT_KEY` / `TESTINGBOT_SECRET`

In CI, prefer environment variables backed by secrets. Never commit credentials to your repository.

## 3. Usage

Configure the `testingbot { }` block with your APKs and the device capabilities you want to run on.

    testingbot {
        // Credentials (optional here if provided via env vars / gradle properties)
        key.set(providers.environmentVariable("TESTINGBOT_KEY"))
        secret.set(providers.environmentVariable("TESTINGBOT_SECRET"))
    
        // The app + instrumented test APKs
        appApk.set(layout.projectDirectory.file("app/build/outputs/apk/debug/app-debug.apk"))
        testApk.set(
            layout.projectDirectory.file("app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk")
        )
    
        // One run is started per capability. Keys are passed through to TestingBot verbatim.
        capabilities.set(
            listOf(
                mapOf("deviceName" to "Pixel.*", "version" to "14", "platformName" to "Android", "realDevice" to true),
                mapOf("deviceName" to "Galaxy S.*", "version" to "13", "platformName" to "Android")
            )
        )
    
        // Optional behavior
        waitForResults.set(true) // poll until the run completes (default true)
        failBuildOnTestFailure.set(true) // default true
        reportXml.set(layout.buildDirectory.file("testingbot/espresso-junit.xml"))
    }

`deviceName` accepts a regular expression, so `"Pixel.*"` matches any Pixel and `"*"` matches any device. Commonly used keys are `deviceName`, `version`, `platformName` (`"Android"`), `realDevice`, `phoneOnly` and `tabletOnly`. Run `./gradlew testingbotDevices` to see what is available on your plan.

## 4. Tasks

    # Upload only
    ./gradlew testingbotUpload
    
    # Build the APKs first, then run Espresso on TestingBot
    ./gradlew assembleDebug assembleDebugAndroidTest testingbotEspresso
    
    # Discover device names/versions for your capabilities
    ./gradlew testingbotDevices

## 5. Android Gradle Plugin auto-wiring

If the `com.android.application` plugin is applied, naming a variant lets the plugin fill in the conventional APK paths and depend on the matching `assemble` tasks automatically.

    testingbot {
        autoWireFromVariant.set("debug") // defaults appApk/testApk + dependsOn assembleDebug(AndroidTest)
        capabilities.set(listOf(mapOf("deviceName" to "Pixel.*", "version" to "14", "platformName" to "Android")))
    }

Now `./gradlew testingbotEspresso` builds the APKs and runs the tests in one go. Explicitly set `appApk` / `testApk` paths always take precedence.

## Full DSL reference

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `key` | `String` | `TESTINGBOT_KEY` / `testingbot.key` | API key |
| `secret` | `String` | `TESTINGBOT_SECRET` / `testingbot.secret` | API secret |
| `apiBaseUrl` | `String` | `https://api.testingbot.com/v1` | API base URL |
| `appApk` | `RegularFile` | — | App APK to upload / test |
| `testApk` | `RegularFile` | — | Instrumented Espresso test APK |
| `capabilities` | `List<Map<String, Any>>` | `[]` | One run per entry; passed through verbatim |
| `espressoOptions` | `Map<String, Any>` | `{}` | Optional run options passed through verbatim |
| `waitForResults` | `Boolean` | `true` | Poll until the run completes |
| `pollIntervalSeconds` | `Long` | `15` | Seconds between status polls |
| `timeoutMinutes` | `Long` | `30` | Max minutes to wait for results |
| `failBuildOnTestFailure` | `Boolean` | `true` | Fail the build when a run reports failures |
| `reportXml` | `RegularFile` | `build/testingbot/espresso-junit.xml` | Where to write the JUnit report |
| `autoWireFromVariant` | `String` | — | Optional AGP variant to auto-wire |

## CI example (GitHub Actions)

    - uses: actions/setup-java@v4
      with: { distribution: temurin, java-version: 21 }
    - run: ./gradlew assembleDebug assembleDebugAndroidTest testingbotEspresso
      env:
        TESTINGBOT_KEY: ${{ secrets.TESTINGBOT_KEY }}
        TESTINGBOT_SECRET: ${{ secrets.TESTINGBOT_SECRET }}

### Looking for more help?

Have questions or need more information? Reach out via email or Slack.

[Email us](https://testingbot.com/contact/new)[Slack Join our Slack](https://join.slack.com/t/testingb0t/shared_invite/zt-3bcw9xch-jk19~6XPs_xBrsAgAedkCw)
