---
title: Swift Tests
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Test Optimization in Datadog > Configure Test Optimization > Swift
  Tests
---

# Swift Tests

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site). ().
{% /alert %}

{% /callout %}

## Compatibility{% #compatibility %}

Supported languages:

| Language    | Version  |
| ----------- | -------- |
| Swift       | \>= 6.2  |
| Objective-C | \>= 2.0  |
| Xcode       | \>= 26.0 |

Supported platforms:

| Platform     | Version  |
| ------------ | -------- |
| iOS / iPadOS | \>= 15.0 |
| macOS        | \>= 11.0 |
| tvOS         | \>= 15.0 |
| macCatalyst  | \>= 13.0 |

Supported test frameworks:

| Framework     | SDK version  | Support level                                     |
| ------------- | ------------ | ------------------------------------------------- |
| XCTest        | All versions | Full support                                      |
| Swift Testing | \>= 2.7.0    | Observation only; advanced features not supported |

## Installing the Swift testing SDK{% #installing-the-swift-testing-sdk %}

There are three ways you can install the testing framework:

{% tab title="Swift Package Manager" %}
### Using Xcode Project{% #using-xcode-project %}

1. Add `dd-sdk-swift-testing` package to your project. It is located at [`https://github.com/DataDog/dd-sdk-swift-testing`](https://github.com/DataDog/dd-sdk-swift-testing).

{% image
   source="https://datadog-docs.imgix.net/images/continuous_integration/swift_package.9611ecb713917ec6fa123e8779423b92.png?auto=format"
   alt="Swift Package" /%}
Link your test targets with the library `DatadogSDKTesting` from the package.
{% image
   source="https://datadog-docs.imgix.net/images/continuous_integration/swift_link2.305fa888ec26d083f004838a3b7ba52c.png?auto=format"
   alt="Swift Linking SPM" /%}
If you run UI Tests and don't use RUM, also add the dependency to your applications running the tests.
### Using Swift Package Project{% #using-swift-package-project %}

1. Add `dd-sdk-swift-testing` to your package dependencies array, for example:

```swift
.package(url: "https://github.com/DataDog/dd-sdk-swift-testing.git", from: "2.5.3")
```
To add the testing framework to your testing targets' dependencies, add the following line to your test targets dependencies array:
```swift
.product(name: "DatadogSDKTesting", package: "dd-sdk-swift-testing")
```

{% /tab %}

{% tab title="Cocoapods" %}

1. Add the `DatadogSDKTesting` dependency to the test targets of your `Podfile`:

```ruby
target 'MyApp' do
  # ...

  target 'MyAppTests' do
    inherit! :search_paths
    pod 'DatadogSDKTesting'
  end
end
```

{% /tab %}

{% tab title="Framework linking" %}

1. Download and decompress `DatadogSDKTesting.zip` from the [release](https://github.com/DataDog/dd-sdk-swift-testing/releases) page.

1. Copy and link your test targets with the resulting XCFramework.

{% image
   source="https://datadog-docs.imgix.net/images/continuous_integration/swift_link.4a944ef7f235907e552c3eea0de6847c.png?auto=format"
   alt="Swift Linking XCFramework" /%}

{% /tab %}

{% alert level="danger" %}
This framework is useful only for testing and should only be linked with the application when running tests. Do not distribute the framework to your users.
{% /alert %}

## Instrumenting your tests{% #instrumenting-your-tests %}

### Configuring SDK{% #configuring-sdk %}

#### Using Xcode Project{% #using-xcode-project %}

To enable testing instrumentation, add the following environment variables to your test target or in the `Info.plist` file as described below. You **must** select your main target in `Expand variables based on` or `Target for Variable Expansion` if you are using test plans:

{% image
   source="https://datadog-docs.imgix.net/images/continuous_integration/swift_env.64873007d72afd6b9e3b784a7c89dcf1.png?auto=format"
   alt="Swift Environments" /%}

{% alert level="danger" %}
You should have your main target in the variables expansion of the environment variables; if not selected, variables are not valid.
{% /alert %}

For UI Tests, environment variables need to be set only in the test target, because the framework automatically injects these values to the application.

#### Using Swift Package Project{% #using-swift-package-project %}

To enable testing instrumentation, you must set the following environment variables to your commandline execution for the tests. You can alternatively set them in the environment before running the tests or you can prepend them to the command:

```

DD_TEST_RUNNER=1 DD_API_KEY= SRCROOT=$PWD swift test ...

or

DD_TEST_RUNNER=1 DD_API_KEY= SRCROOT=$PWD xcodebuild test -scheme ...
```

Set all these variables in your test target:

{% dl %}

{% dt %}
`DD_TEST_RUNNER`
{% /dt %}

{% dd %}
Enables or disables the instrumentation of tests. Set this value to `$(DD_TEST_RUNNER)` so you can enable and disable test instrumentation with a environment variable defined outside of the test process (for example, in the CI build).**Default**: `false`**Recommended**: `$(DD_TEST_RUNNER)`
{% /dd %}

{% dt %}
`DD_API_KEY`
{% /dt %}

{% dd %}
The [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) used to upload the test results.**Default**: `(empty)`
{% /dd %}

{% dt %}
`DD_TEST_SESSION_NAME`
{% /dt %}

{% dd %}
Identifies a group of tests, such as `integration-tests`, `unit-tests` or `smoke-tests`.**Environment variable**: `DD_TEST_SESSION_NAME`**Default**: (CI job name + test command)**Example**: `unit-tests`, `integration-tests`, `smoke-tests`
{% /dd %}

{% dt %}
`DD_SERVICE`
{% /dt %}

{% dd %}
Name of the service or library under test.**Default**: The repository name**Example**: `my-ios-app`
{% /dd %}

{% dt %}
`DD_ENV`
{% /dt %}

{% dd %}
Name of the environment where tests are being run. Set this value to `$(DD_ENV)` so you can use an environment variable at runtime for setting it.**Default**: `none`**Recommended**: `$(DD_ENV)`**Examples**: `ci`, `local`
{% /dd %}

{% dt %}
`SRCROOT`
{% /dt %}

{% dd %}
The path to the project location. If using Xcode, use `$(SRCROOT)` for the value, because it is automatically set by it.**Default**: `(empty)`**Recommended**: `$(SRCROOT)`**Example**: `/Users/ci/source/MyApp`
{% /dd %}

{% /dl %}

For more information about `service` and `env` reserved tags, see [Unified Service Tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging).

Additionally, configure the Datadog site to use the selected one ():

{% dl %}

{% dt %}
`DD_SITE` (Required)
{% /dt %}

{% dd %}
The [Datadog site](https://docs.datadoghq.com/getting_started/site/) to upload results to.**Default**: `datadoghq.com`**Selected site**: 
{% /dd %}

{% /dl %}

## Collecting Git metadata{% #collecting-git-metadata %}

Datadog uses Git information for visualizing your test results and grouping them by repository, branch, and commit. Git metadata is automatically collected by the test instrumentation from CI provider environment variables and the local `.git` folder in the project path, if available.

If you are running tests in non-supported CI providers or with no `.git` folder, you can set the Git information manually using environment variables. These environment variables take precedence over any auto-detected information. Set the following environment variables to provide Git information:

{% dl %}

{% dt %}
`DD_GIT_REPOSITORY_URL`
{% /dt %}

{% dd %}
URL of the repository where the code is stored. Both HTTP and SSH URLs are supported.**Example**: `git@github.com:MyCompany/MyApp.git`, `https://github.com/MyCompany/MyApp.git`
{% /dd %}

{% dt %}
`DD_GIT_BRANCH`
{% /dt %}

{% dd %}
Git branch being tested. Leave empty if providing tag information instead.**Example**: `develop`
{% /dd %}

{% dt %}
`DD_GIT_TAG`
{% /dt %}

{% dd %}
Git tag being tested (if applicable). Leave empty if providing branch information instead.**Example**: `1.0.1`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_SHA`
{% /dt %}

{% dd %}
Full commit hash.**Example**: `a18ebf361cc831f5535e58ec4fae04ffd98d8152`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_MESSAGE`
{% /dt %}

{% dd %}
Commit message.**Example**: `Set release number`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_AUTHOR_NAME`
{% /dt %}

{% dd %}
Commit author name.**Example**: `John Smith`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_AUTHOR_EMAIL`
{% /dt %}

{% dd %}
Commit author email.**Example**: `john@example.com`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_AUTHOR_DATE`
{% /dt %}

{% dd %}
Commit author date in ISO 8601 format.**Example**: `2021-03-12T16:00:28Z`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_COMMITTER_NAME`
{% /dt %}

{% dd %}
Commit committer name.**Example**: `Jane Smith`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_COMMITTER_EMAIL`
{% /dt %}

{% dd %}
Commit committer email.**Example**: `jane@example.com`
{% /dd %}

{% dt %}
`DD_GIT_COMMIT_COMMITTER_DATE`
{% /dt %}

{% dd %}
Commit committer date in ISO 8601 format.**Example**: `2021-03-12T16:00:28Z`
{% /dd %}

{% /dl %}

### Running tests{% #running-tests %}

After installation, run your tests as you normally do, for example using the `xcodebuild test` command. Tests, network requests, and application crashes are instrumented automatically. Pass your environment variables when running your tests in the CI, for example:

```

DD_TEST_RUNNER=1 DD_SITE= xcodebuild \
  -project "MyProject.xcodeproj" \
  -scheme "MyScheme" \
  -destination "platform=macOS,arch=arm64" \
  test
```

### UI tests{% #ui-tests %}

### RUM Integration{% #rum-integration %}

If the application being tested is instrumented using RUM, your UI tests results and their generated RUM sessions are automatically linked. Learn more about RUM in the [RUM iOS Integration](https://docs.datadoghq.com/tests/swift_tests/) guide. An iOS RUM version >= 1.10 is needed.

Environment variables need to be set only in the test target, because the framework automatically injects these values to the application.

### Test Optimisation SDK{% #test-optimisation-sdk %}

If you don't use RUM, you can link your application target with the Test SDK. The SDK adds auto-instrumentation to your application, gathers network requests and logs, and attaches them to the test traces.

Environment variables need to be set only in the test target, because the framework automatically injects these values to the application.

## Swift Testing framework{% #swift-testing-framework %}

Starting from version 2.7.0, the Datadog SDK supports the Swift Testing framework for test observation. Only observation is supported; advanced Swift Testing features are not supported.

### Setting up Swift Testing observation{% #setting-up-swift-testing-observation %}

The dependency setup is the same as for XCTest. See Installing the Swift testing SDK for installation instructions.

To enable observation for your Swift Testing tests:

1. Import `DatadogSDKTesting` in your test source files:

```swift
import DatadogSDKTesting
import Testing
```
Add the `.datadogTesting` trait to your test suites or standalone test functions:
```swift
@Suite(.datadogTesting)
struct MyTestSuite {
    @Test func myTest() {
        // ...
    }
}

// For standalone test functions:
@Test(.datadogTesting) func myStandaloneTest() {
    // ...
}
```

The remaining configuration, including environment variables and CI provider setup, is the same as for XCTest. See Instrumenting your tests for details.

## Additional optional configuration{% #additional-optional-configuration %}

For the following configuration settings:

- `Boolean` variables can use any of: `1`, `0`, `true`, `false`, `YES`, or `NO`
- `String` list variables accept a list of elements separated by `,` or `;`

### Enabling auto-instrumentation{% #enabling-auto-instrumentation %}

{% dl %}

{% dt %}
`DD_ENABLE_STDOUT_INSTRUMENTATION`
{% /dt %}

{% dd %}
Captures messages written to `stdout` (for example, `print()`) and reports them as logs. This may impact your bill. (Boolean)
{% /dd %}

{% dt %}
`DD_ENABLE_STDERR_INSTRUMENTATION`
{% /dt %}

{% dd %}
Captures messages written to `stderr` (for example, `NSLog()`, UITest steps) and reports them as logs. This may impact your bill. (Boolean)
{% /dd %}

{% /dl %}

### Disabling auto-instrumentation{% #disabling-auto-instrumentation %}

The framework enables auto-instrumentation of all supported libraries, but in some cases this might not be desired. You can disable auto-instrumentation of certain libraries by setting the following environment variables (or in the `Info.plist` file as described below):

{% dl %}

{% dt %}
`DD_DISABLE_NETWORK_INSTRUMENTATION`
{% /dt %}

{% dd %}
Disables all network instrumentation (Boolean)
{% /dd %}

{% dt %}
`DD_DISABLE_RUM_INTEGRATION`
{% /dt %}

{% dd %}
Disables integration with RUM Sessions (Boolean)
{% /dd %}

{% dt %}
`DD_DISABLE_SOURCE_LOCATION`
{% /dt %}

{% dd %}
Disables test source code location and Codeowners (Boolean)
{% /dd %}

{% dt %}
`DD_DISABLE_CRASH_HANDLER`
{% /dt %}

{% dd %}
Disables crash handling and reporting. (Boolean)
{% /dd %}

{% /dl %}

{% alert level="danger" %}
If you disable crash reporting, tests that crash are not reported at all, and don't appear as test failures. If you need to disable crash handling for any of your tests, run them as a separate target, so you don't disable it for the others.
{% /alert %}

### Network auto-instrumentation{% #network-auto-instrumentation %}

For Network auto-instrumentation, you can configure these additional settings:

{% dl %}

{% dt %}
`DD_DISABLE_HEADERS_INJECTION`
{% /dt %}

{% dd %}
Disables all injection of tracing headers (Boolean)
{% /dd %}

{% dt %}
`DD_INSTRUMENTATION_EXTRA_HEADERS`
{% /dt %}

{% dd %}
Specific extra headers that you want to log (String List)
{% /dd %}

{% dt %}
`DD_EXCLUDED_URLS`
{% /dt %}

{% dd %}
URLs that you don't want to log or inject headers into (String List)
{% /dd %}

{% dt %}
`DD_ENABLE_RECORD_PAYLOAD`
{% /dt %}

{% dd %}
Enables reporting a subset (1024 bytes) of the payloads in requests and responses (Boolean)
{% /dd %}

{% dt %}
`DD_MAX_PAYLOAD_SIZE`
{% /dt %}

{% dd %}
Sets the maximum size reported from the payload. Default `1024` (Integer)
{% /dd %}

{% dt %}
`DD_DISABLE_NETWORK_CALL_STACK`
{% /dt %}

{% dd %}
Disables the call stack information in the network spans (Boolean)
{% /dd %}

{% dt %}
`DD_ENABLE_NETWORK_CALL_STACK_SYMBOLICATED`
{% /dt %}

{% dd %}
Shows the call stack information with not only the method name, but also the precise file and line information. May impact your tests' performance (Boolean)
{% /dd %}

{% /dl %}

### Infrastructure test correlation{% #infrastructure-test-correlation %}

If you are running tests in your own infrastructure (macOS or simulator tests), you can correlate your tests with your infrastructure metrics by installing the Datadog Agent and setting the following:

{% dl %}

{% dt %}
`DD_CIVISIBILITY_REPORT_HOSTNAME`
{% /dt %}

{% dd %}
Reports the hostname of the machine launching the tests (Boolean)
{% /dd %}

{% /dl %}

You can also disable or enable specific auto-instrumentation in some of the tests from Swift or Objective-C by importing the module `DatadogSDKTesting` and using the class: `DDInstrumentationControl`.

## Custom tags{% #custom-tags %}

### Environment variables{% #environment-variables %}

You can use `DD_TAGS` environment variable (or in the `Info.plist` file as described below). It must contain pairs of `key:tag` separated by spaces. For example:

```bash
DD_TAGS=tag-key-0:tag-value-0 tag-key-1:tag-value-1
```



If one of the values starts with the `$` character, it is replaced with an environment variable of the same name (if it exists), for example:

```bash
DD_TAGS=home:$HOME
```



Using the `$` character also supports replacing an environment variable at the beginning of a value if contains non-environment variable supported characters (`a-z`, `A-Z` or `_`), for example:

```bash
FOO = BAR
DD_TAGS=key1:$FOO-v1 // expected: key1:BAR-v1
```



### Inside a test method{% #inside-a-test-method %}

You can add custom tags inside your test methods. The static property `DDTest.current` will return the current test instance if called inside the test method scope.

```swift
// Somewhere inside the test method
DDTest.current?.setTag(key: "key1", value: "value1")
// test continues normally
// ...
```

### OpenTelemetry{% #opentelemetry %}

**Note**: Using OpenTelemetry is only supported for Swift.

Datadog Swift testing framework uses [OpenTelemetry](https://opentelemetry.io/) as the tracing technology under the hood. You can access the OpenTelemetry tracer using `DDInstrumentationControl.openTelemetryTracer` and use any OpenTelemetry API. For example, to add a tag or attribute:

```swift
import DatadogSDKTesting
import OpenTelemetryApi

let tracer = DDInstrumentationControl.openTelemetryTracer as? Tracer
let span = tracer?.spanBuilder(spanName: "ChildSpan").startSpan()
span?.setAttribute(key: "OTTag2", value: "OTValue2")
span?.end()
```

The test target needs to link explicitly with `opentelemetry-swift`.

### Reporting code coverage{% #reporting-code-coverage %}

When code coverage is available, the Datadog SDK (v2.2.7+) reports it under the `test.code_coverage.lines_pct` tag for your test sessions.

In Xcode, you can enable gathering of code coverage in your Test Plan or Test Scheme, depending on your project configuration.

You can see the evolution of the test coverage in the **Coverage** tab of a test session.

## Using Info.plist for configuration{% #using-infoplist-for-configuration %}

Alternatively to setting environment variables, all configuration values can be provided by adding them to the `Info.plist` file of the Test bundle (not the App bundle). If the same setting is set both in an environment variable and in the `Info.plist` file, the environment variable takes precedence.

## CI provider environment variables{% #ci-provider-environment-variables %}

{% tab title="Jenkins" %}

| Environment variable | Value                   |
| -------------------- | ----------------------- |
| `JENKINS_URL`        | `$(JENKINS_URL)`        |
| `WORKSPACE`          | `$(WORKSPACE)`          |
| `BUILD_TAG`          | `$(BUILD_TAG)`          |
| `BUILD_NUMBER`       | `$(BUILD_NUMBER)`       |
| `BUILD_URL`          | `$(BUILD_URL)`          |
| `JOB_NAME`           | `$(JOB_NAME)`           |
| `DD_CUSTOM_TRACE_ID` | `$(DD_CUSTOM_TRACE_ID)` |

Additional Git configuration for physical device testing:

| Environment variable | Value           |
| -------------------- | --------------- |
| `GIT_COMMIT`         | `$(GIT_COMMIT)` |
| `GIT_URL`            | `$(GIT_URL)`    |
| `GIT_URL_1`          | `$(GIT_URL_1)`  |
| `GIT_BRANCH`         | `$(GIT_BRANCH)` |

{% /tab %}

{% tab title="CircleCI" %}

| Environment variable       | Value                         |
| -------------------------- | ----------------------------- |
| `CIRCLECI`                 | `$(CIRCLECI)`                 |
| `CIRCLE_WORKING_DIRECTORY` | `$(CIRCLE_WORKING_DIRECTORY)` |
| `CIRCLE_BUILD_NUM`         | `$(CIRCLE_BUILD_NUM)`         |
| `CIRCLE_BUILD_URL`         | `$(CIRCLE_BUILD_URL)`         |
| `CIRCLE_WORKFLOW_ID`       | `$(CIRCLE_WORKFLOW_ID)`       |
| `CIRCLE_PROJECT_REPONAME`  | `$(CIRCLE_PROJECT_REPONAME)`  |

Additional Git configuration for physical device testing:

| Environment variable    | Value                      |
| ----------------------- | -------------------------- |
| `CIRCLE_SHA1`           | `$(CIRCLE_SHA1)`           |
| `CIRCLE_REPOSITORY_URL` | `$(CIRCLE_REPOSITORY_URL)` |
| `CIRCLE_BRANCH`         | `$(CIRCLE_BRANCH)`         |
| `CIRCLE_TAG`            | `$(CIRCLE_TAG)`            |

{% /tab %}

{% tab title="GitLab CI" %}

| Environment variable | Value                |
| -------------------- | -------------------- |
| `GITLAB_CI`          | `$(GITLAB_CI)`       |
| `CI_PROJECT_DIR`     | `$(CI_PROJECT_DIR)`  |
| `CI_JOB_STAGE`       | `$(CI_JOB_STAGE)`    |
| `CI_JOB_NAME`        | `$(CI_JOB_NAME)`     |
| `CI_JOB_URL`         | `$(CI_JOB_URL)`      |
| `CI_PIPELINE_ID`     | `$(CI_PIPELINE_ID)`  |
| `CI_PIPELINE_IID`    | `$(CI_PIPELINE_IID)` |
| `CI_PIPELINE_URL`    | `$(CI_PIPELINE_URL)` |
| `CI_PROJECT_PATH`    | `$(CI_PROJECT_PATH)` |
| `CI_PROJECT_URL`     | `$(CI_PROJECT_URL)`  |

Additional Git configuration for physical device testing:

| Environment variable  | Value                    |
| --------------------- | ------------------------ |
| `CI_COMMIT_SHA`       | `$(CI_COMMIT_SHA)`       |
| `CI_REPOSITORY_URL`   | `$(CI_REPOSITORY_URL)`   |
| `CI_COMMIT_BRANCH`    | `$(CI_COMMIT_BRANCH)`    |
| `CI_COMMIT_TAG`       | `$(CI_COMMIT_TAG)`       |
| `CI_COMMIT_MESSAGE`   | `$(CI_COMMIT_MESSAGE)`   |
| `CI_COMMIT_AUTHOR`    | `$(CI_COMMIT_AUTHOR)`    |
| `CI_COMMIT_TIMESTAMP` | `$(CI_COMMIT_TIMESTAMP)` |

{% /tab %}

{% tab title="Travis" %}

| Environment variable       | Value                         |
| -------------------------- | ----------------------------- |
| `TRAVIS`                   | `$(TRAVIS)`                   |
| `TRAVIS_BUILD_DIR`         | `$(TRAVIS_BUILD_DIR)`         |
| `TRAVIS_BUILD_ID`          | `$(TRAVIS_BUILD_ID)`          |
| `TRAVIS_BUILD_NUMBER`      | `$(TRAVIS_BUILD_NUMBER)`      |
| `TRAVIS_BUILD_WEB_URL`     | `$(TRAVIS_BUILD_WEB_URL)`     |
| `TRAVIS_JOB_WEB_URL`       | `$(TRAVIS_JOB_WEB_URL)`       |
| `TRAVIS_REPO_SLUG`         | `$(TRAVIS_REPO_SLUG)`         |
| `TRAVIS_PULL_REQUEST_SLUG` | `$(TRAVIS_PULL_REQUEST_SLUG)` |

Additional Git configuration for physical device testing:

| Environment variable         | Value                           |
| ---------------------------- | ------------------------------- |
| `TRAVIS_PULL_REQUEST_BRANCH` | `$(TRAVIS_PULL_REQUEST_BRANCH)` |
| `TRAVIS_BRANCH`              | `$(TRAVIS_BRANCH)`              |
| `TRAVIS_COMMIT`              | `$(TRAVIS_COMMIT)`              |
| `TRAVIS_TAG`                 | `$(TRAVIS_TAG)`                 |
| `TRAVIS_COMMIT_MESSAGE`      | `$(TRAVIS_COMMIT_MESSAGE)`      |

{% /tab %}

{% tab title="GitHub Actions" %}

| Environment variable | Value                   |
| -------------------- | ----------------------- |
| `GITHUB_WORKSPACE`   | `$(GITHUB_WORKSPACE)`   |
| `GITHUB_REPOSITORY`  | `$(GITHUB_REPOSITORY)`  |
| `GITHUB_RUN_ID`      | `$(GITHUB_RUN_ID)`      |
| `GITHUB_RUN_NUMBER`  | `$(GITHUB_RUN_NUMBER)`  |
| `GITHUB_WORKFLOW`    | `$(GITHUB_WORKFLOW)`    |
| `GITHUB_SHA`         | `$(GITHUB_SHA)`         |
| `GITHUB_SERVER_URL`  | `$(GITHUB_SERVER_URL)`  |
| `GITHUB_RUN_ATTEMPT` | `$(GITHUB_RUN_ATTEMPT)` |

Additional Git configuration for physical device testing:

| Environment variable | Value                  |
| -------------------- | ---------------------- |
| `GITHUB_REF`         | `$(GITHUB_REF)`        |
| `GITHUB_HEAD_REF`    | `$(GITHUB_HEAD_REF)`   |
| `GITHUB_REPOSITORY`  | `$(GITHUB_REPOSITORY)` |

{% /tab %}

{% tab title="Buildkite" %}

| Environment variable            | Value                              |
| ------------------------------- | ---------------------------------- |
| `BUILDKITE`                     | `$(BUILDKITE)`                     |
| `BUILDKITE_BUILD_CHECKOUT_PATH` | `$(BUILDKITE_BUILD_CHECKOUT_PATH)` |
| `BUILDKITE_BUILD_ID`            | `$(BUILDKITE_BUILD_ID)`            |
| `BUILDKITE_BUILD_NUMBER`        | `$(BUILDKITE_BUILD_NUMBER)`        |
| `BUILDKITE_BUILD_URL`           | `$(BUILDKITE_BUILD_URL)`           |
| `BUILDKITE_PIPELINE_SLUG`       | `$(BUILDKITE_PIPELINE_SLUG)`       |
| `BUILDKITE_JOB_ID`              | `$(BUILDKITE_JOB_ID)`              |

Additional Git configuration for physical device testing:

| Environment variable           | Value                             |
| ------------------------------ | --------------------------------- |
| `BUILDKITE_COMMIT`             | `$(BUILDKITE_COMMIT)`             |
| `BUILDKITE_REPO`               | `$(BUILDKITE_REPO)`               |
| `BUILDKITE_BRANCH`             | `$(BUILDKITE_BRANCH)`             |
| `BUILDKITE_TAG`                | `$(BUILDKITE_TAG)`                |
| `BUILDKITE_MESSAGE`            | `$(BUILDKITE_MESSAGE)`            |
| `BUILDKITE_BUILD_AUTHOR`       | `$(BUILDKITE_BUILD_AUTHOR)`       |
| `BUILDKITE_BUILD_AUTHOR_EMAIL` | `$(BUILDKITE_BUILD_AUTHOR_EMAIL)` |

{% /tab %}

{% tab title="Bitbucket Pipelines" %}

| Environment variable       | Value                         |
| -------------------------- | ----------------------------- |
| `BITBUCKET_CLONE_DIR`      | `$(BITBUCKET_CLONE_DIR)`      |
| `BITBUCKET_BUILD_NUMBER`   | `$(BITBUCKET_BUILD_NUMBER)`   |
| `BITBUCKET_PIPELINE_UUID`  | `$(BITBUCKET_PIPELINE_UUID)`  |
| `BITBUCKET_REPO_FULL_NAME` | `$(BITBUCKET_REPO_FULL_NAME)` |

Additional Git configuration for physical device testing:

| Environment variable       | Value                         |
| -------------------------- | ----------------------------- |
| `BITBUCKET_COMMIT`         | `$(BITBUCKET_COMMIT)`         |
| `BITBUCKET_GIT_SSH_ORIGIN` | `$(BITBUCKET_GIT_SSH_ORIGIN)` |
| `BITBUCKET_BRANCH`         | `$(BITBUCKET_BRANCH)`         |
| `BITBUCKET_TAG`            | `$(BITBUCKET_TAG)`            |

{% /tab %}

{% tab title="AppVeyor" %}

| Environment variable     | Value                       |
| ------------------------ | --------------------------- |
| `APPVEYOR`               | `$(APPVEYOR)`               |
| `APPVEYOR_BUILD_FOLDER`  | `$(APPVEYOR_BUILD_FOLDER)`  |
| `APPVEYOR_BUILD_ID`      | `$(APPVEYOR_BUILD_ID)`      |
| `APPVEYOR_BUILD_NUMBER`  | `$(APPVEYOR_BUILD_NUMBER)`  |
| `APPVEYOR_REPO_TAG_NAME` | `$(APPVEYOR_REPO_TAG_NAME)` |
| `APPVEYOR_REPO_NAME`     | `$(APPVEYOR_REPO_NAME)`     |

Additional Git configuration for physical device testing:

| Environment variable                     | Value                                       |
| ---------------------------------------- | ------------------------------------------- |
| `APPVEYOR_REPO_COMMIT`                   | `$(APPVEYOR_REPO_COMMIT)`                   |
| `APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH` | `$(APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH)` |
| `APPVEYOR_REPO_BRANCH`                   | `$(APPVEYOR_REPO_BRANCH)`                   |
| `APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED`  | `$(APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED)`  |
| `APPVEYOR_REPO_COMMIT_AUTHOR`            | `$(APPVEYOR_REPO_COMMIT_AUTHOR)`            |
| `APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL`      | `$(APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL)`      |

{% /tab %}

{% tab title="Azure Pipelines" %}

| Environment variable             | Value                               |
| -------------------------------- | ----------------------------------- |
| `TF_BUILD`                       | `$(TF_BUILD)`                       |
| `BUILD_SOURCESDIRECTORY`         | `$(BUILD_SOURCESDIRECTORY)`         |
| `BUILD_BUILDID`                  | `$(BUILD_BUILDID)`                  |
| `BUILD_DEFINITIONNAME`           | `$(BUILD_DEFINITIONNAME)`           |
| `SYSTEM_TEAMPROJECTID`           | `$(SYSTEM_TEAMPROJECTID)`           |
| `SYSTEM_TEAMFOUNDATIONSERVERURI` | `$(SYSTEM_TEAMFOUNDATIONSERVERURI)` |
| `SYSTEM_JOBID`                   | `$(SYSTEM_JOBID)`                   |
| `SYSTEM_TASKINSTANCEID`          | `$(SYSTEM_TASKINSTANCEID)`          |
| `SYSTEM_JOBDISPLAYNAME`          | `$(SYSTEM_JOBDISPLAYNAME)`          |
| `SYSTEM_STAGEDISPLAYNAME`        | `$(SYSTEM_STAGEDISPLAYNAME)`        |

Additional Git configuration for physical device testing:

| Environment variable                     | Value                                       |
| ---------------------------------------- | ------------------------------------------- |
| `BUILD_SOURCEVERSION`                    | `$(BUILD_SOURCEVERSION)`                    |
| `BUILD_REPOSITORY_URI`                   | `$(BUILD_REPOSITORY_URI)`                   |
| `BUILD_SOURCEBRANCH`                     | `$(BUILD_SOURCEBRANCH)`                     |
| `SYSTEM_PULLREQUEST_SOURCECOMMITID`      | `$(SYSTEM_PULLREQUEST_SOURCECOMMITID)`      |
| `SYSTEM_PULLREQUEST_SOURCEBRANCH`        | `$(SYSTEM_PULLREQUEST_SOURCEBRANCH)`        |
| `SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI` | `$(SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI)` |
| `BUILD_SOURCEVERSIONMESSAGE`             | `$(BUILD_SOURCEVERSIONMESSAGE)`             |
| `BUILD_REQUESTEDFORID`                   | `$(BUILD_REQUESTEDFORID)`                   |
| `BUILD_REQUESTEDFOREMAIL`                | `$(BUILD_REQUESTEDFOREMAIL)`                |

{% /tab %}

{% tab title="Bitrise" %}

| Environment variable            | Value                              |
| ------------------------------- | ---------------------------------- |
| `BITRISE_SOURCE_DIR`            | `$(BITRISE_SOURCE_DIR)`            |
| `BITRISE_TRIGGERED_WORKFLOW_ID` | `$(BITRISE_TRIGGERED_WORKFLOW_ID)` |
| `BITRISE_BUILD_SLUG`            | `$(BITRISE_BUILD_SLUG)`            |
| `BITRISE_BUILD_NUMBER`          | `$(BITRISE_BUILD_NUMBER)`          |
| `BITRISE_BUILD_URL`             | `$(BITRISE_BUILD_URL)`             |

Additional Git configuration for physical device testing:

| Environment variable               | Value                                 |
| ---------------------------------- | ------------------------------------- |
| `GIT_REPOSITORY_URL`               | `$(GIT_REPOSITORY_URL)`               |
| `BITRISE_GIT_COMMIT`               | `$(BITRISE_GIT_COMMIT)`               |
| `BITRISE_GIT_BRANCH`               | `$(BITRISE_GIT_BRANCH)`               |
| `BITRISE_GIT_TAG`                  | `$(BITRISE_GIT_TAG)`                  |
| `GIT_CLONE_COMMIT_HASH`            | `$(GIT_CLONE_COMMIT_HASH)`            |
| `BITRISE_GIT_MESSAGE`              | `$(BITRISE_GIT_MESSAGE)`              |
| `GIT_CLONE_COMMIT_MESSAGE_SUBJECT` | `$(GIT_CLONE_COMMIT_MESSAGE_SUBJECT)` |
| `GIT_CLONE_COMMIT_MESSAGE_BODY`    | `$(GIT_CLONE_COMMIT_MESSAGE_BODY)`    |
| `GIT_CLONE_COMMIT_AUTHOR_NAME`     | `$(GIT_CLONE_COMMIT_AUTHOR_NAME)`     |
| `GIT_CLONE_COMMIT_AUTHOR_EMAIL`    | `$(GIT_CLONE_COMMIT_AUTHOR_EMAIL)`    |
| `GIT_CLONE_COMMIT_COMMITER_NAME`   | `$(GIT_CLONE_COMMIT_COMMITER_NAME)`   |
| `GIT_CLONE_COMMIT_COMMITER_EMAIL`  | `$(GIT_CLONE_COMMIT_COMMITER_EMAIL)`  |

{% /tab %}

{% tab title="Xcode Cloud" %}

| Environment variable    | Value                |
| ----------------------- | -------------------- |
| `DD_GIT_REPOSITORY_URL` | The repository URL   |
| `CI_WORKSPACE`          | `$(CI_WORKSPACE)`    |
| `CI_COMMIT`             | `$(CI_COMMIT)`       |
| `CI_BUILD_ID`           | `$(CI_BUILD_ID)`     |
| `CI_BUILD_NUMBER`       | `$(CI_BUILD_NUMBER)` |
| `CI_WORKFLOW`           | `$(CI_WORKFLOW)`     |
| `CI_TAG`                | `$(CI_TAG)`          |
| `CI_BRANCH`             | `$(CI_BRANCH)`       |
| `CI_GIT_REF`            | `$(CI_GIT_REF)`      |

{% /tab %}

## Best practices{% #best-practices %}

Follow these practices to take full advantage of the testing framework and Test Optimization.

### Generate symbols file when building{% #generate-symbols-file-when-building %}

Build your code in Xcode using `DWARF with dSYM File` (or `-Xswiftc -debug-info-format=dwarf` if building with `swift`)

The testing framework uses symbol files for some of its functionality, including: symbolicating crashes, reporting test source location, and reporting code owners. It automatically generates the symbol file when debug symbols are embedded in the binaries, but it can take some extra time to load.

### Disable sandbox for UI Tests on macOS{% #disable-sandbox-for-ui-tests-on-macos %}

In some Xcode versions, UI Test bundles are built with a sandbox by default. The settings that come with a sandbox prevent the testing framework from being run by some system commands with `xcrun`, so you need to disable it.

Disable the sandbox by adding Entitlements to the UI Test runner bundle, then adding `App Sandbox = NO` to them. You can also create an `.entitlement` file and add it to the Signing Build Settings. This file should should include the following content:

```xml
<key>com.apple.security.app-sandbox</key>
 <false/>
```

### Test session name `DD_TEST_SESSION_NAME`{% #test-session-name-dd_test_session_name %}

Use `DD_TEST_SESSION_NAME` to define the name of the test session and the related group of tests. Examples of values for this tag would be:

- `unit-tests`
- `integration-tests`
- `smoke-tests`
- `flaky-tests`
- `ui-tests`
- `backend-tests`

If `DD_TEST_SESSION_NAME` is not specified, the default value used is a combination of the:

- CI job name
- Command used to run the tests (such as `swift test`)

The test session name needs to be unique within a repository to help you distinguish different groups of tests.

#### When to use `DD_TEST_SESSION_NAME`{% #when-to-use-dd_test_session_name %}

There's a set of parameters that Datadog checks to establish correspondence between test sessions. The test command used to execute the tests is one of them. If the test command contains a string that changes for every execution, such as a temporary folder, Datadog considers the sessions to be unrelated to each other. For example:

- `swift test --temp-dir=/var/folders/t1/rs2htfh55mz9px2j4prmpg_c0000gq/T`

Datadog recommends using `DD_TEST_SESSION_NAME` if your test commands vary between executions.

## Further reading{% #further-reading %}

- [Explore Test Results and Performance](https://docs.datadoghq.com/tests)
- [Speed up your test jobs with Test Impact Analysis](https://docs.datadoghq.com/tests/test_impact_analysis/swift)
- [Troubleshooting Test Optimization](https://docs.datadoghq.com/tests/troubleshooting/)
