TestKase
TestKase
|Docs
AutomateMobileEspresso

Getting started

Build your app and androidTest APKs, get your access key, and run your first Espresso build on a real Android phone with four curl calls.

Four calls: upload the app, upload the test suite, start a build, read the result. This page does each one with curl, so you can paste it into any CI step.

1. Build the two APKs

From your Android project, the same Gradle tasks you already use for connectedAndroidTest:

./gradlew assembleDebug assembleDebugAndroidTest

That gives you two files:

FileWhat it is
app/build/outputs/apk/debug/app-debug.apkThe app — what your tests exercise
app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apkThe test suite — your Espresso tests and their runner

Both must be ordinary .apk files signed with the same key, which is what Gradle's debug build does for you. See Uploading APKs for what we accept.

2. Get your access key

Open API Keys in your dashboard and copy your key. It starts with xyz_.

That key is the only thing that authenticates you. Send it either way:

  • HTTP Basic — the key is the password: curl -u "x:$TESTKASE_ACCESS_KEY" …. The x is a placeholder username we do not check.
  • Bearer — Authorization: Bearer $TESTKASE_ACCESS_KEY.

It is the same key your Appium and Selenium tests use. Keep it in your CI's secret store; the examples below read it from TESTKASE_ACCESS_KEY.

A missing, wrong or expired key always answers 401 with "That access token isn't valid."

3. Upload the app

curl -u "x:$TESTKASE_ACCESS_KEY" \
  -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
  https://hub.testkase.com/espresso/v1/app
{
  "app_url": "farm://app-3f9c01a2b4c5d6e7",
  "app_name": "app-debug",
  "package": "com.acme",
  "expires_at": "2027-01-07T09:12:44.000Z"
}

Keep app_url. package is read from the APK itself.

This upload must finish within five minutes. For a large APK or a slow CI connection, use the direct upload instead. It sends the file straight to storage and gives you the same app_url.

4. Upload the test suite

curl -u "x:$TESTKASE_ACCESS_KEY" \
  -F "file=@app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk" \
  https://hub.testkase.com/espresso/v1/test-suite
{
  "test_suite_url": "farm://suite-81ad02c4e9f1b367",
  "test_package": "com.acme.test",
  "target_package": "com.acme",
  "runner": "androidx.test.runner.AndroidJUnitRunner",
  "expires_at": "2027-01-07T09:13:02.000Z"
}

Keep test_suite_url. target_package must be your app's package, or the build in the next step is refused.

5. Start a build

Name the devices as "<device name>-<Android version>", for example "Pixel 8-17" (device names and Android versions vary — copy them from the capability generator). The capability generator lists the Android devices and versions we have right now.

curl -u "x:$TESTKASE_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  https://hub.testkase.com/espresso/v1/build \
  -d '{
    "app": "farm://app-3f9c01a2b4c5d6e7",
    "testSuite": "farm://suite-81ad02c4e9f1b367",
    "devices": ["Pixel 8-17", "OnePlus Nord 6-16"],
    "buildTag": "nightly-412"
  }'
{ "build_id": "5b1e7c2a-9d4f-4e1b-8a63-2f0c7d9e4b18", "message": "Success" }

Everything is checked before any device is taken: a wrong URL, a suite built for another app or a device name we don't have is a 400 straight away, and nothing is billed. Every field is on Starting a build.

6. Read the result

curl -u "x:$TESTKASE_ACCESS_KEY" \
  https://hub.testkase.com/espresso/v1/builds/5b1e7c2a-9d4f-4e1b-8a63-2f0c7d9e4b18
{
  "build_id": "5b1e7c2a-9d4f-4e1b-8a63-2f0c7d9e4b18",
  "status": "running",
  "project": null,
  "buildTag": "nightly-412",
  "devices": [
    { "device": "Pixel 8-17", "sessionId": "0747163a-5e2d-4c8b-9f10-6a3b2c1d0e9f", "status": "running",
      "tests": { "total": 3, "passed": 2, "failed": 0, "skipped": 1 } },
    { "device": "OnePlus Nord 6-16", "sessionId": "e6ceae40-1b7c-4d2e-8f3a-9c0b5d6e7f81", "status": "passed",
      "tests": { "total": 3, "passed": 2, "failed": 0, "skipped": 1 } }
  ]
}

Poll it until status is no longer queued or running, then gate your CI on it: passed is green, anything else is not. What each status means is on Results.

A simple poll loop for a CI step:

BUILD_ID=5b1e7c2a-9d4f-4e1b-8a63-2f0c7d9e4b18
while true; do
  STATUS=$(curl -s -u "x:$TESTKASE_ACCESS_KEY" \
    "https://hub.testkase.com/espresso/v1/builds/$BUILD_ID" | jq -r .status)
  echo "build $BUILD_ID: $STATUS"
  case "$STATUS" in queued|running) sleep 30 ;; *) break ;; esac
done
[ "$STATUS" = "passed" ]

7. See it in the dashboard

Open Automate → Mobile Apps → Runs. Your build is listed under its buildTag (or its project if you sent no tag, or "Espresso build" if you sent neither). Open a device's session for the per-test video, the logs and the All Commands tab.

The status response does not include a dashboard link, so a recognisable buildTag — a CI run number or commit SHA — is the easiest way to find it.

Next