> [!WARNING]
>
> **Preview**
>
>
> This product or feature is
>
> subject to the "Pre-GA Offerings Terms" in the General Service Terms section
> of the [Service Specific
> Terms](https://docs.cloud.google.com/terms/service-terms#1).
>
> Pre-GA products and features are available "as is" and might have limited support.
>
> For more information, see the
> [launch stage descriptions](https://cloud.google.com/products/#product-launch-stages).

The **Developer Device Platform (DDP)** replaces the legacy *Firebase Test Lab* console
and Test Lab CLI workflows with a unified, high-performance, and secure
Google Cloud-first testing CLI: `gcloud beta device-run`

This guide provides command-line translations and mappings of flags from Test
Lab (or Flank) to DDP. Use this guidance to migrate your tests manually. See
[Migrate from Firebase Test Lab to Developer Device Platform](https://docs.cloud.google.com/developer-device-platform/migrate.md.txt) for automation
tools, benefits, key differences and migration tips.

## Sharding migration

DDP modernizes sharding configurations by natively replacing both Flank's
complex Cloud Storage-based smart sharding and Test Lab's uniform sharding.

### Uniform Sharding

- Set `--sharding-option=uniform`.
- Set `--uniform-sharding-count={count}` (1-20 for physical, 1-200 for
  virtual).

- **Legacy Firebase Test Lab** : `--num-uniform-shards {N}`

- **DDP CLI** : `--sharding-option=uniform --uniform-sharding-count={N}`

### Smart Sharding

- Set `--sharding-option=smart`.
- Set `--smart-sharding-target-duration={duration}` (e.g. `2m`, `10m`, `1h`; valid range: `2m` to `1h`).
- Set `--smart-sharding-record-name={record_name}` (points to the YAML tracking record inside `--bucket-name` under `automation/smart-sharding/`).
- Set `--smart-sharding-max-shard-count={max_count}` (optional maximum limit: 0-20 for physical, 0-200 for virtual).

Using historical 30-day timing metadata:

- **Legacy Flank**:

  ```yaml
  max-test-shards: 10
  shard-time: 120
  smart-flank-gcs-path: gs://my-bucket/smart-sharding/timing-record.yaml
  ```
- **DDP CLI**:

  ```bash
  --sharding-option=smart \
  --smart-sharding-max-shard-count=10 \
  --smart-sharding-target-duration=2m \
  --smart-sharding-record-name=timing-record \
  --bucket-name=my-bucket
  ```

  > [!NOTE]
  > **Note:** Specify `--smart-sharding-record-name` as the YAML base name (excluding the file extension).

## Declarative YAML configuration (`--flags-file`)

For complex configurations or teams that prefer maintaining version-controlled
files instead of long terminal commands, `gcloud` provides a universal
`--flags-file` argument preprocessor (see `$ gcloud topic flags-file`):

### Android

```bash
gcloud beta device-run sessions submit instrumentation --flags-file=device-run-flags.yaml
```

### iOS

```bash
gcloud alpha device-run sessions submit xctest --flags-file=device-run-flags.yaml
```

> [!NOTE]
> **Note:** **Why keys require `--`:** `gcloud` injects YAML keys directly into the CLI parser as command-line flags. Every key in the YAML file must be prefixed with `--` (e.g. `--device:`, `--apps:`). Without `--`, `gcloud` rejects them as unrecognized positional arguments.

Here is an example demonstrating a multi-valued list and dictionary flags:

### Android

```yaml
# device-run-flags.yaml
--device:

    -   mediumphone-arm-32
    -   shiba-36
--apps:
    -   app-debug.apk
    -   test-helper.apk
--test: app-debug-androidTest.apk
--bucket-name: my-bucket
--sharding-option: smart
--smart-sharding-target-duration: 2m
--smart-sharding-record-name: timing-record
--paths-to-pull:
    -   /sdcard/screenshots
    -   /sdcard/coverage.ec
--additional-test-options:
  coverage: "true"
  clearPackageData: "true"
```

### iOS

```yaml
# device-run-flags.yaml
--device:

    -   iphonese3-18-4
    -   iphone16pro-18-3
--test: MyTests.zip
--additional-apps:
    -   helper-app.ipa
--xcode-version: '16.4'
--xctest-timeout: 15m
--other-files-to-push:
  /local/path/test-config.json: com.example.app:/Documents/test-config.json
--paths-to-pull:
    -   com.example.app:/Documents/screenshots
--labels:
  env: staging
  team: mobile-qa
```

## End-to-end command translation examples

See these standard and complex translations for concrete examples.

### Example: Run a standard Instrumentation test

**Legacy Firebase CLI:**

```bash
gcloud firebase test android run \
  --app=app-debug.apk \
  --test=app-debug-androidTest.apk \
  --device model=shiba,version=36 \
  --timeout=5m \
  --num-flaky-test-attempts=2 \
  --directories-to-pull=/sdcard/screenshots \
  --environment-variables key=value
```

**DDP CLI translation:**

```bash
gcloud beta device-run sessions submit instrumentation \
  --device=shiba-36 \
  --apps=app-debug.apk \
  --test=app-debug-androidTest.apk \
  --instrumentation-timeout=5m \
  --flaky-test-attempts=3 \
  --paths-to-pull=/sdcard/screenshots \
  --additional-test-options key=value
```

> [!NOTE]
> **Note:** Firebase Test Lab retry limit (`R=2`) is translated to total execution attempts (`A=3`) in DDP.

### Example: Migrate a complex flank YAML configuration

**Legacy Flank configuration:**

```yaml
app: app-debug.apk
test: app-debug-androidTest.apk
device:
  -   model: shiba
    version: 36
shard-time: 120
smart-flank-gcs-path: gs://my-bucket/smart-sharding/timing-record.yaml
```

**DDP CLI translation:**

```bash
gcloud beta device-run sessions submit instrumentation \
  --device=shiba-36 \
  --apps=app-debug.apk \
  --test=app-debug-androidTest.apk \
  --bucket-name=my-bucket \
  --sharding-option=smart \
  --smart-sharding-target-duration=2m \
  --smart-sharding-record-name=timing-record
```

## Post-execution and result retrieval

Since DDP does not launch with a graphical web UI (like the legacy Firebase
Console), developers must manage, describe, and inspect results directly using
the CLI or programmatic REST APIs:

```bash
# 1. List active and completed test sessions
gcloud beta device-run sessions list

# 2. Get a summary and direct Cloud Storage bucket link of a session's results
gcloud beta device-run sessions describe session-number

# 3. Get detailed metadata and print full results
gcloud beta device-run sessions describe session-number --full

# 4. Cancel a running session (replaces console cancellation)
gcloud beta device-run sessions cancel session-number
```

## Flag mapping reference

Here is the flag mapping for migrating test configurations from Flank or `gcloud
firebase test android/ios run` to the new DDP `gcloud beta device-run sessions
submit instrumentation` and `gcloud alpha device-run sessions submit xctest`
commands.

> [!TIP]
> **Tip:** Append `--help` to any `gcloud` command to see detailed usage information.

### Core parameters and assets

| Legacy Parameter (Test Lab / Flank) | Target DDP Parameter | Format / Conversion Logic |
|---|---|---|
| Flank `--project` | `--project` | Standard Google Cloud global flag (`--project=PROJECT_ID`) or active Google Cloud CLI configuration. |
| `--client-details` | `--labels` | **Dictionary** of `key=value` pairs to attach to the test session. |
| `--other-files` | `--other-files-to-push` | **Dictionary** . Comma-separated `SOURCE=DEST` list of auxiliary files to push to the device before the test run. |

### Device configuration and targeting

| Legacy Parameter (Test Lab / Flank) | Target DDP Parameter | Format / Conversion Logic |
|---|---|---|
| `--device model={M},version={V}` | `--device={M}-{V}` | REQUIRED **String** that maps model and OS version to a single `--device` ID string. DDP's `--device` flag accepts multiple device IDs separated by commas (ex. `--device=shiba-34,tokay-36`) or multiple `--device` flags, each specifying a distinct device ID (ex. `--device=shiba-34 --device=tokay-36`). |

### Execution control and flakiness

| Legacy Parameter (Test Lab / Flank) | Target DDP Parameter | Format / Conversion Logic |
|---|---|---|
| `--async` | `--async` | **Boolean**. Maps 1:1. Command executes synchronously by default. Pass this to return to the terminal immediately. Exits immediately after file upload and prints operation and session IDs. |
| `--num-flaky-test-attempts {R}` | `--flaky-test-attempts {A}` | **Integer** . The maximum number of execution attempts per test shard. Convert retry count *R* to total attempts *A* limit: *A* = *R* + 1 (defaults to 1). |

### Output and storage

| Legacy Parameter (Test Lab / Flank) | Target DDP Parameter | Format / Conversion Logic |
|---|---|---|
| `--results-bucket` | `--bucket-name` | **String** . Cloud Storage bucket where test artifacts, including local input files, test output files, and smart sharding timing records, are uploaded (defaults to `gs://[PROJECT_ID]-devicerun` if not specified). |
| `--results-dir` | *Managed automatically* | **Unsupported** . Sub-paths are automatically organized in Cloud Storage under `automation/sessions/{session_id}/`. |
| `--directories-to-pull` | `--paths-to-pull` | **List**. Directories to download from the device after the test run. |

### Sharding configuration

| Legacy Parameter (Test Lab / Flank) | Target DDP Parameter | Format / Conversion Logic |
|---|---|---|
| `--num-uniform-shards {N}` | `--sharding-option=uniform --uniform-sharding-count={N}` | **String** and **Integer**. Combined flag configuration both activates uniform sharding strategy and sets max shard count (valid count range: 1-20 physical, 1-200 virtual). |
| Flank `--max-test-shards {N}` | `--sharding-option=smart --smart-sharding-max-shard-count={N}` | **String** and **Integer**. Combined flag configuration both activates smart sharding strategy and sets max shard count (valid count range: 0-20 physical, 0-200 virtual). |
| Flank `--shard-time {S}` | `--sharding-option=smart --smart-sharding-target-duration={S}` | REQUIRED **String** . Activates smart sharding with target execution time (ex. `2m`, `10m`, `1h`). Valid range: `2m` to `1h`. |
| Flank `--smart-flank-gcs-path` | `--smart-sharding-record-name={name} --bucket-name={bucket}` | REQUIRED **String** . Name of the sharding record YAML (excluding file extension) inside `--bucket-name` under `smart-sharding/` in Cloud Storage. |

### Android-specific flags

Use this table to map legacy `gcloud firebase test android run` and Flank
Android flags to their new `gcloud beta device-run sessions submit
instrumentation` equivalents:

| Test Type | Feature Group | Legacy Parameter (`firebase android` / Flank) | Target DDP Parameter | Format / Conversion Logic |
|---|---|---|---|---|
| Common Android | Core parameters and assets | `--app` | `--apps` | **List** . If multiple application APKs/AABs are supplied, pass them all to `--apps` in the order to be installed on the device. Path can be local or in Cloud Storage (`gs://...`). |
| Common Android | Core parameters and assets | `--additional-apks` | `--apps` | **List** . Merge additional list values directly into the main `--apps` list. |
| Common Android | Core parameters and assets | `--obb-files` | `--other-files-to-push` | **Dictionary** in `SOURCE=DEST` format. Push OBB files directly to the target device path (`/sdcard/Android/obb/{package_name}/`). |
| Common Android | Device configuration and targeting | `--device locale={L}` | `--locale={L}` | **String** . Maps device locale to top-level `--locale` flag (`language-region`, ex. `--locale=en-US`) to switch the device to before running the test. |
| Common Android | Device configuration and targeting | `--device orientation={O}` | `--orientation={O}` | **String** . Maps device orientation to top-level `--orientation` flag (`portrait` or `landscape`). |
| Common Android | Device configuration and targeting | *N/A* | `--coordinates` | **String** . Mocks device GPS location coordinates (ex. `--coordinates=37.4220,-122.0841`). |
| Common Android | Execution control and flakiness | `--grant-permissions` | *Automated Default* | **Automated** . Runtime permissions are granted automatically by default (equivalent to `--grant-permissions=all`). |
| Common Android | Output and storage | *N/A* | `--dumpsys` | **String** . Collect system state using `dumpsys` (values: `always`, `on-failure`). |
| Common Android | Output and storage | *N/A* | `--bugreport` | **String** . Collect a full `bugreport` from the device (values: `always`, `on-failure`). |
| Common Android | Output and storage | `--record-video` | `--video` | **String** . When to record video of the device screen during the test run. Valid values are `always` or `on-failure`. |
| Android Instrumentation | Core parameters and assets | `--type=instrumentation` | `sessions submit instrumentation` | Sub-command structure determines test type instead of a `--type` flag. |
| Android Instrumentation | Core parameters and assets | `--test` | `--test` | REQUIRED **String**. Path to the test APK containing Instrumentation tests, either local or in Cloud Storage. |
| Android Instrumentation | Execution control and flakiness | `--timeout` | `--instrumentation-timeout` | **Duration** (ex. `10m`, `20s`, `1h`). Valid range: `1m` to `3h` (defaults to `5m`). |
| Android Instrumentation | Execution control and flakiness | *N/A* | `--flaky-test-parallel-retry` | **Boolean** . Whether to retry test failures in parallel (defaults to `false` for sequential execution). |
| Android Instrumentation | Execution control and flakiness | *N/A* | `--flaky-test-retry-level` | **String** . Defines whether to retry at the `shard` or individual `test` level (defaults to `shard`). |
| Android Instrumentation | Test runner and targets | `--test-runner-class` | `--test-runner-class` | **String** . The fully-qualified Instrumentation test runner class (ex. `com.foo.MyRunner`) to use. If not specified, a default runner class is determined by examining the application's manifest. |
| Android Instrumentation | Test runner and targets | `--test-targets` | `--test-targets` | **Dictionary** of test targets or target filters to run. Each target must be fully qualified with the package name or class name supporting keys such as `package`, `notPackage`, `class`, `notClass`, `annotation`, `notAnnotation`, and `size`. Formats `testfile` or `notTestfile` are not supported. |
| Android Instrumentation | Test runner and targets | `--use-orchestrator` | `--orchestrator-version` | Whether to use Android Test Orchestrator. Takes `auto` (default orchestrator) or specific version string (ex. `1.6`). Available versions can be queried using `gcloud beta device-run software-versions list`. |
| Android Instrumentation | Test runner and targets | `--environment-variables` | `--additional-test-options` | **Dictionary** of options passed to the Instrumentation test runner. Formats supported in `--test-targets` are not allowed here. |

### iOS-specific flags

Use this table to map legacy `gcloud firebase test ios run` flags to their new
`device-run` equivalents:

| Legacy Parameter (`firebase ios`) | Target DDP Parameter | Format / Conversion Logic |
|---|---|---|
| `--test` | `--test` | Path to built XCTest zip. |
| `--device model={M},version={V}` | `--device={M}-{V}` | Target device ID string. |
| `--timeout` | `--xctest-timeout` | Duration (e.g. `5m`). Range: `1m` to `1h`. |
| `--xcode-version` | `--xcode-version` | Catalog ID or version string of Xcode to use (ex. `xcode-16-4` or `16.4`). Available versions can be queried using `gcloud beta device-run software-versions list`. |
| `--results-bucket` | `--bucket-name` | Custom destination GCS bucket. |
| `--async` | `--async` | Synchronous by default, pass to exit immediately. |
| `--other-files` | `--other-files-to-push` | Dictionary in `SOURCE=BUNDLE_ID:DEST` format. |
| `--directories-to-pull` | `--paths-to-pull` | List in `BUNDLE_ID:DEVICE_PATH` format. |
| `--additional-ipas` | `--additional-apps` | List of helper IPAs to install prior to test. |
| `--record-video` | `--video` | When to record video: `always` or `on-failure`. One video is recorded for each UI test case (iOS 17 or later). |
| `--xctestrun-file` | `--xctestrun-file` | Path to custom `.xctestrun` plist. |
| `--num-flaky-test-attempts` | `--flaky-test-attempts` | Integer count of retry attempts (e.g. `3`). |
| `--client-details` | `--labels` | Key-value pairs (`KEY=VALUE`). |

## Feedback and questions

[Contact us](https://docs.cloud.google.com/developer-device-platform/quickstart.md.txt#contact-us) to file bugs and
feature requests or join our discussion forum.