Skip to content

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:

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

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:

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

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 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).
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:

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:

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

TypeScript / Playwright

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

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.