---
title: Fastlane Integration for TestingBot
description: Upload your iOS and Android app builds to TestingBot straight from your
  Fastlane lanes with the fastlane-plugin-testingbot plugin, ready for automated and
  manual testing on real devices and simulators.
source_url:
  html: https://testingbot.com/support/integrations/fastlane
  md: https://testingbot.com/support/integrations/fastlane/index.md
---
# Fastlane Integration

[Fastlane](https://fastlane.tools) is the most popular open-source toolchain to automate building and releasing iOS and Android apps. Our [fastlane-plugin-testingbot](https://github.com/testingbot/testingbot-fastlane-plugin) plugin uploads your app builds to TestingBot Storage straight from a Fastlane lane, so they are ready for automated and manual testing on our real devices, emulators and simulators.

Because the upload runs as a regular Fastlane action, you can chain it right after `gym` (iOS) or `gradle` (Android) in the same lane, no manual upload step and no extra scripts.

## Prerequisites

- A [TestingBot account](https://testingbot.com/users/sign_up) with an API key and secret, which you can find in the [member area](https://testingbot.com/members/user/edit).
- Fastlane installed in your project (see the [fastlane setup guide](https://docs.fastlane.tools/getting-started/ios/setup/)).
- An app build to upload: `.apk` or `.aab` for Android, `.ipa` for iOS real devices, or a `.zip` for the iOS simulator.

## Install the plugin

Add the plugin to your project with Fastlane's plugin command:

    fastlane add_plugin testingbot

This adds the plugin to your `fastlane/Pluginfile` and updates your `Gemfile` and `Gemfile.lock`. Commit these files so the plugin is installed automatically on your CI machines.

## Set your credentials

The plugin authenticates with your TestingBot key and secret. The recommended way is to provide them as environment variables, so they are not stored in your `Fastfile`:

    export TESTINGBOT_KEY="your-api-key"
    export TESTINGBOT_SECRET="your-api-secret"

On CI services such as GitHub Actions, CircleCI or Bitrise, store `TESTINGBOT_KEY` and `TESTINGBOT_SECRET` as secret/encrypted environment variables instead of hard-coding them.

You can also pass the credentials inline with the `testingbot_key` and `testingbot_secret` parameters of the action, but environment variables are preferred.

## Upload your app

The plugin adds the `upload_to_testingbot` action. In its simplest form, point it at a local build:

    lane :upload do
      upload_to_testingbot(
        file_path: "./app/build/outputs/apk/debug/app-debug.apk"
      )
    end

When you build in the same lane, you can drop `file_path` entirely. The action picks up the build that `gradle` or `gym` just produced:

    # Android
    lane :android_build_and_upload do
      gradle(task: "assembleDebug")
      upload_to_testingbot
    end
    
    # iOS
    lane :ios_build_and_upload do
      gym(scheme: "MyApp")
      upload_to_testingbot
    end

You can also have TestingBot fetch the build from a remote URL, instead of uploading a local file:

    upload_to_testingbot(
      remote_url: "https://example.com/builds/MyApp.ipa"
    )

Then run your lane:

    fastlane upload

## Options

The `upload_to_testingbot` action accepts the following parameters. Each one also reads from the matching environment variable when it is not passed explicitly.

| Parameter | Environment variable | Required | Description |
| --- | --- | --- | --- |
| `testingbot_key` | `TESTINGBOT_KEY` | Yes | Your TestingBot API key. |
| `testingbot_secret` | `TESTINGBOT_SECRET` | Yes | Your TestingBot API secret. |
| `file_path` | `TESTINGBOT_FILE_PATH` | No | Path to the local app build. Auto-resolves from the previous `gym` or `gradle` step when omitted. |
| `remote_url` | `TESTINGBOT_REMOTE_URL` | No | A public URL for TestingBot to fetch the build from, instead of uploading a local file. |
| `app_url` | `TESTINGBOT_REPLACE_APP_URL` | No | An existing `tb://` app identifier to replace in place, so the app keeps a stable URL across builds. |

To keep a stable app identifier across builds, pass the existing `tb://` URL with `app_url`:

    upload_to_testingbot(
      file_path: "./MyApp.ipa",
      app_url: "tb://YOUR_APP_KEY"
    )

## Output values

After a successful upload the action returns a `tb://<appkey>` identifier. You can reference this app in your Appium capabilities (set `app` to the `tb://` URL) or open it in [App Live](https://testingbot.com/members/apps/devices/new) for manual testing.

The value is available through the lane context and environment for use later in the same lane:

    lane :build_test do
      gradle(task: "assembleDebug")
      app_url = upload_to_testingbot
    
      UI.message("Uploaded app: #{app_url}")
    
      # also available via:
      lane_context[SharedValues::TESTINGBOT_APP_URL]
      lane_context[SharedValues::TESTINGBOT_APP_KEY]
      lane_context[SharedValues::TESTINGBOT_STORAGE_RESPONSE]
      ENV["TESTINGBOT_APP_URL"]
      ENV["TESTINGBOT_APP_KEY"]
    end

## Notes & limits

- Supported formats: `.apk` and `.aab` (Android), `.ipa` (iOS real devices) and `.zip` (iOS simulator).
- Uploaded apps are stored in your [TestingBot Storage](https://testingbot.com/support/api#upload) and shared with your team, so any team member can run automated or manual tests against them.
- The plugin is open source and MIT licensed. Issues and pull requests are welcome on [GitHub](https://github.com/testingbot/testingbot-fastlane-plugin).

### 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)
