# Integration Test Environment Variables

Pass configuration values and pipeline variables into your integration test runs using the `integrationTestEnvironmentVariables` pipeline parameter.

---

## 📋 Overview

| Property          | Value                                                                   |
| ----------------- | ----------------------------------------------------------------------- |
| **Goal**          | Configure environment variables available to integration tests in CI/CD |
| **Prerequisites** | A project with integration tests enabled in its pipeline                |
| **Applies to**    | .NET and TypeScript integration tests (PR and main pipelines)           |

Integration tests often need runtime configuration that is not part of your application code — for example, the URL of a deployed API, a feature flag, or a test-specific override. The `integrationTestEnvironmentVariables` parameter passes these values directly into the integration test step as process-level environment variables.

---

## ⚙️ How It Works

The parameter accepts a list of `name`/`value` pairs. Each entry is injected as an environment variable on the test task when the pipeline runs:

```text
Your pipeline YAML
  └─ integrationTestEnvironmentVariables
       └─ Orchestrator (azure-app-orchestrator-v3.yml)
            └─ tests.integration-tests.config.environmentVariables
                 └─ Activity (run-integration-tests.yml)
                      └─ env:
                           MY_VAR: value
```

Both .NET (.NET `DotNetCoreCLI@2` test task) and TypeScript (`npm run test:integration`) activities honor this parameter — the variables are available to your test process regardless of language.

---

## 🚀 Configuration

Add `integrationTestEnvironmentVariables` to **both** your PR pipeline and your main pipeline. The parameter is optional — omit it entirely if your tests need no extra configuration.

### Basic Example

```yaml
extends:
  template: azure-dotnet-api-v3.yml@templates
  parameters:
    applicationName: ${{ variables.ApplicationName }}
    projectId: ${{ variables.ProjectId }}
    dotNetVersion: '10.x'
    integrationTestEnvironmentVariables:
      - name: FEATURE_FLAG_NEW_CLAIMS_FLOW
        value: 'true'
      - name: TEST_TENANT_ID
        value: 'test'
```

Apply the same block to `azure-dotnet-api-pr-v3.yml` so tests have the same configuration during PR validation.

### TypeScript / React projects

The parameter works identically for TypeScript pipelines:

```yaml
extends:
  template: azure-react-web-pr-v3.yml@templates
  parameters:
    applicationName: ${{ variables.ApplicationName }}
    projectId: ${{ variables.ProjectId }}
    nodeVersion: '22.x'
    integrationTestEnvironmentVariables:
      - name: VITE_API_BASE_URL
        value: 'https://api.test.example.com'
```

---

## 🔒 Using Pipeline Variables and Secrets

Hard-coding values in pipeline YAML is only appropriate for non-sensitive, non-environment-specific configuration. For secrets or values that differ per environment, reference Azure DevOps pipeline variables instead.

### Referencing a pipeline variable

```yaml
integrationTestEnvironmentVariables:
  - name: INTEGRATION_TEST_CLIENT_SECRET
    value: $(IntegrationTestClientSecret)    # Azure DevOps variable syntax
  - name: INTEGRATION_TEST_BASE_URL
    value: $(IntegrationTestBaseUrl)
```

> ⚠️ **Security:** Never embed secrets as literal strings in your pipeline YAML. Store them as secret variables in an Azure DevOps Variable Group and reference them with `$(VariableName)`. See [Settings and Secrets](../settings-and-secrets.md) for variable group setup.

### Variable group setup

1. Create or use your existing variable group (named to match your `secretsVariableGroupName`).
2. Add the required test variables as **Secret** type entries.
3. Reference them in the pipeline with `$(VariableName)`.

```yaml
extends:
  template: azure-dotnet-api-pr-v3.yml@templates
  parameters:
    applicationName: ${{ variables.ApplicationName }}
    projectId: ${{ variables.ProjectId }}
    dotNetVersion: '10.x'
    secretsVariableGroupName: 'it-api-exp-myapp'   # Brings in secrets from the library
    integrationTestEnvironmentVariables:
      - name: INTEGRATION_API_KEY
        value: $(IntegrationApiKey)                 # Resolved from the variable group
```

---

## 💡 Reading Variables in Your Tests

### .NET

Use `Environment.GetEnvironmentVariable` to read the injected value:

```csharp
var tenantId = Environment.GetEnvironmentVariable("TEST_TENANT_ID") ?? "test";
var featureEnabled = Environment.GetEnvironmentVariable("FEATURE_FLAG_NEW_CLAIMS_FLOW") == "true";
```

For Aspire-based tests you can also wire the value through `IConfiguration`:

```csharp
builder.Configuration["FeatureFlags:NewClaimsFlow"] =
    Environment.GetEnvironmentVariable("FEATURE_FLAG_NEW_CLAIMS_FLOW") ?? string.Empty;
```

### TypeScript / Playwright

Variables are available on `process.env` in Node.js:

```typescript
const baseUrl = process.env.VITE_API_BASE_URL ?? 'http://localhost:5173';
```

---

## ✅ Common Scenarios

| Scenario                          | Variable name pattern   | Example value         |
| --------------------------------- | ----------------------- | --------------------- |
| Toggle a feature flag for tests   | `FEATURE_FLAG_*`        | `'true'`              |
| Provide a test client ID          | `INTEGRATION_CLIENT_ID` | `$(ClientId)`         |
| Set a test tenant identifier      | `TEST_TENANT_ID`        | `'test'`              |
| Pass a connection string override | `ConnectionStrings__*`  | `$(TestDbConnection)` |

---

## 🔍 Troubleshooting

**Variable is `null` or empty in tests**

- Confirm the variable is defined in **both** the PR and main pipeline YAML files.
- If using `$(VariableName)`, verify the Azure DevOps Variable Group is linked and the pipeline has permission to access it.
- Check pipeline logs for the `🧪 Run Integration Tests` step to confirm the variable was set (note: secret values are masked).

**Variable available locally but not in CI**

- Local runs use whatever is in your shell environment. In CI the values only come from `integrationTestEnvironmentVariables` — ensure all required variables are listed in the parameter.

**Changes apply to main pipeline but not PR**

- The parameter must be set independently in each pipeline file. Confirm the block is present in both `azure-pipelines-api-pr.yml` and `azure-pipelines-api.yml`.

---

## 📚 Related Documentation

- [API Integration Testing](./api-integration-testing.md) — Writing integration tests with Aspire
- [Web Integration Testing](./web-integration-testing.md) — Playwright-based end-to-end tests
- [Settings and Secrets](../settings-and-secrets.md) — Managing secrets with Azure DevOps Variable Groups
- [Pipeline Troubleshooting](../pipeline-troubleshooting.md) — Diagnosing pipeline failures
