> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qa.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Mobile pull request testing

> Upload each pull request iOS or Android build and review that binary.

Native mobile pull requests do not produce a preview URL. QA.tech tests the **binary your CI built for that PR**, not a deployed website. After the upload, pin the run or change review to that build with `applicationBuildShortId`.

If the GitHub App auto-runs without a build override, it uses the application's default environment (the last configured staging or production build). That is not the PR binary.

## Choose an integration mode

| Mode                               | What runs                                                                                                                             | When to use                                       |
| :--------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------ |
| **Test plan** (API-driven)         | A plan you already maintain (smoke, regression)                                                                                       | Deployment gates, required checks, known coverage |
| **Change review** (AI exploratory) | The same review agent as the [GitHub App](/configuration/github-app): selects relevant tests, fills gaps, posts a native PR/MR review | You want AI to decide what to test from the diff  |

Both modes use the same upload. They differ only in how you start testing after you have a build short ID.

<Note>
  Create the mobile application in **Settings → Applications & Envs** before CI
  uploads. See [Mobile App Testing](/test-features/mobile-app-testing). Passing
  `applicationBuildShortId` creates or reuses an environment for that build; you
  do not add a new environment in the UI for every PR.
</Note>

## Prerequisites

* Mobile testing enabled for the organization (contact [support](mailto:hi@qa.tech) if it is not)
* A mobile application in **Settings → Applications & Envs**. Each row has a short ID (`app_…`). Use the three-dot menu → **Copy Short ID**. You do not need a test plan for this. **Test Plans → API Integration** only lists apps already on a plan.
* A [test plan](/core-concepts/test-plans) short ID for API-driven runs, **or** the [GitHub App](/configuration/github-app) / [GitLab MR integration](/configuration/gitlab) connected for change reviews
* An API token from **Organization Settings → API Keys**, stored as `QATECH_API_TOKEN` (GitHub) or `QA_TECH_API_TOKEN` (GitLab). Project-scoped keys are fine. Org-scoped keys need `projectShortId` on list and upload APIs.
* A project short ID for GitHub Actions (for example `proj_abc123`). Copy it from the project URL or Settings.
* A **simulator or emulator** build in CI: Android `.apk`, or iOS `.app` compressed as `.zip` or `.tar.gz`. Device and App Store `.ipa` files cannot run on simulators. See [Preparing Your App Build](/test-features/mobile-app-testing#preparing-your-app-build).

## How it works

```
PR opened or updated
  → CI builds the app (simulator APK or zipped .app)
  → CI uploads the file (presigned URL, then create build)
  → CI starts a test plan or change review pinned to applicationBuildShortId
  → QA.tech creates or reuses an environment for that exact build
  → Tests run on a cloud simulator or emulator
```

See the [Application Builds API](/api-reference/application-builds) for request and response details.

## Upload the PR build

Run this **after** your compile step, on every PR. Replace `app_gXeBl2` and the file path.

```bash theme={null}
APP_ID="app_gXeBl2"
BUILD_FILE="app/build/outputs/apk/debug/app-debug.apk"
FILE_NAME=$(basename "$BUILD_FILE")

UPLOAD_RESPONSE=$(curl -sSf -X POST "https://api.qa.tech/v1/applications/$APP_ID/builds/upload-url" \
  -H "Authorization: Bearer $QATECH_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"fileName\": \"$FILE_NAME\"}")
UPLOAD_URL=$(echo "$UPLOAD_RESPONSE" | jq -r '.uploadUrl')
BUILD_TOKEN=$(echo "$UPLOAD_RESPONSE" | jq -r '.buildToken')

curl -sSf -X PUT "$UPLOAD_URL" \
  --upload-file "$BUILD_FILE" \
  -H "Content-Type: application/octet-stream"

BUILD_RESPONSE=$(curl -sSf -X POST "https://api.qa.tech/v1/applications/$APP_ID/builds" \
  -H "Authorization: Bearer $QATECH_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"platform\": \"android\", \"buildToken\": \"$BUILD_TOKEN\"}")
BUILD_SHORT_ID=$(echo "$BUILD_RESPONSE" | jq -r '.applicationBuildShortId')
echo "Uploaded $BUILD_SHORT_ID"
```

For iOS, zip the `.app` first, set `"platform": "ios"`, and upload the archive:

```bash theme={null}
zip -r AppName.zip AppName.app
BUILD_FILE="$PWD/AppName.zip"
```

The presigned URL expires in about two hours. Maximum file size is 4 GB.

To install companion apps on the same device, upload those builds too and pass their short IDs in `otherApplicationBuildShortIds`. See [Other Apps](/test-features/mobile-app-testing#other-apps).

Per-CI steps for starting the review are on [GitHub](/pr-testing/github#mobile-build), [GitLab](/pr-testing/gitlab#mobile-build), and [Bitrise](/pr-testing/bitrise#mobile-build). To run a test plan against the same build, see [Mobile regression testing](/regression-testing/agents/mobile).

## Network access

Mobile sessions use a different outbound IP pool than web tests. If the app talks to a firewalled backend, allowlist the ranges under [Settings → Network](https://app.qa.tech/current-project/settings/network) (**Mobile Testing IP Whitelist**). See [Network Access](/test-features/mobile-app-testing#network-access).

## Troubleshooting

**Tests ran, but against the old app**

The job did not pass `applicationBuildShortId`, or GitHub App **Auto-run on PRs** started a second review on the default environment. Pin the CI trigger to the uploaded build and turn auto-run off when CI owns the review.

**Upload or create-build fails for iOS**

The file is a device or App Store `.ipa`. Produce a simulator `.app` and upload a `.zip` or `.tar.gz`. See [Preparing Your App Build](/test-features/mobile-app-testing#preparing-your-app-build).

**Change review starts but never comments on the PR**

The GitHub App is not installed, or it does not have access to the repository. The Change Review Action still needs that App connection so the agent can read the PR and post the review. See [Change Review Action setup](/configuration/github-actions#change-review-action).

**Login or API calls fail in the emulator**

The backend is blocking mobile testing IPs. Update the [Mobile Testing IP Whitelist](/test-features/mobile-app-testing#network-access).
