Environment Variables
Define project-level key-value pairs for dynamic test configuration. Use variables to switch between environments, manage credentials, and keep your tests flexible without editing step data.
Overview
Environment variables are project-level key-value pairs that inject dynamic values into your tests at runtime. Instead of hardcoding URLs, usernames, or configuration values directly into test steps, you define them as variables and reference them using the {{key}} substitution syntax.
This approach provides several benefits:
- Environment switching — change a single variable to point all tests at staging, production, or a local dev server
- Credential management — keep usernames and passwords in one place instead of scattered across test steps
- Configuration flexibility — update test behavior without modifying test definitions
- Reusability — the same test works across different environments by swapping variable values
Managing Variables
Environment variables are managed through the EnvironmentVariablesModal, accessible from the Tests page in your project.
Open the Variables Modal
From the Tests page, click the Environment Variables button (or gear/settings icon). This opens the EnvironmentVariablesModal, which displays all variables currently defined for the project.
Add a Variable
Click Add Variable. Enter a key (the name you will reference in tests) and a value (the string that will be substituted at runtime). Keys should be descriptive and use camelCase or SCREAMING_SNAKE_CASE by convention.
Edit or Delete
To modify an existing variable, update its key or value directly in the table. To remove a variable, click the delete button next to it. Changes are not persisted until you save.
Save
Click Save to persist all changes to the project. The updated variables will take effect the next time any test in the project is run.
Substitution Syntax
To reference a variable in a test step, use double curly braces around the key name:
{{variableName}}
The runner replaces the entire {{variableName}} token with the variable's value before executing the step. Substitution is purely textual — the token is replaced with the string value as-is.
Where Substitution Works
Variable substitution is applied to all text-based step fields before execution. This includes:
| Field | Example Usage |
|---|---|
| URL fields | {{baseUrl}}/login in Navigate steps |
| Selector fields | {{loginFormSelector}} in Click, Fill, Assert steps |
| Fill values | {{username}} in the value field of Fill steps |
| Assert values | {{expectedTitle}} in Assert-Text or Assert-Value steps |
| Wait values | {{loadTimeout}} in Wait steps (converted to number at runtime) |
| All other text fields | Any string field in any step type supports substitution |
How Substitution Works
Before test execution begins, the runner performs variable substitution as a preprocessing step:
- The runner loads all environment variables defined on the project
- For each step in the test (including steps resolved from reusable flows), it scans all text fields
- Every occurrence of
{{key}}is replaced with the corresponding variable value - If a
{{key}}has no matching variable, it is left as-is (the literal string{{key}}remains) - The substituted steps are then executed normally
Examples
Example: Base URL
Set a variable for your application's base URL, then reference it in Navigate steps:
| Variable Key | Variable Value |
|---|---|
baseUrl |
https://staging.example.com |
In your Navigate step, set the URL to:
{{baseUrl}}/login
At runtime, this resolves to https://staging.example.com/login. To switch to production, change the variable value to https://app.example.com and re-run — no test edits needed.
Example: Login Credentials
Store credentials as variables for use in Fill steps:
| Variable Key | Variable Value |
|---|---|
username |
admin@example.com |
password |
TestPassword123! |
In your Fill steps:
- Fill
#emailwith{{username}} - Fill
#passwordwith{{password}}
This keeps credentials centralized and makes it easy to update them without editing individual tests or flows.
Example: Multiple Variables in One Field
You can use multiple variables in a single field:
{{baseUrl}}/api/v{{apiVersion}}/users
With baseUrl = https://staging.example.com and apiVersion = 2, this resolves to https://staging.example.com/api/v2/users.
Variables in Control Flow Conditions
Environment variables integrate with control flow conditions. Two condition types work directly with variables:
- variable-equals — evaluates to true if the specified variable's value exactly matches a given string
- variable-contains — evaluates to true if the specified variable's value contains a given substring
This lets you create conditional test logic based on the current environment. For example, you might skip certain steps when running against production by checking an environment variable:
If: variable-equals "environment" = "staging"
Fill #seed-data with "test-data-001"
Click button#seed
End If
In this example, the seed data steps only execute when the environment variable is set to staging, allowing the same test to run safely in both staging and production.
Scope and Sharing
Environment variables are stored on the project and are shared across all tests in that project. Every test and every reusable flow within the project has access to the same set of variables. Variables are not shared across projects.
This means:
- Changing a variable value affects every test in the project on the next run
- All tests in a project share the same environment configuration
- If two projects need different variable sets, they are completely independent
Best Practices
Use environment variables for any value that might change between environments (URLs, credentials, feature flags) so you can switch environments by changing variables, not by editing tests.
- Use for environment-specific values — URLs, API endpoints, hostnames, and ports that differ between dev, staging, and production.
- Centralize credentials — store test usernames, passwords, and API keys as variables. Update them in one place when they change.
- Feature flags — use variables to control test behavior based on feature availability. Combine with control flow conditions to skip or include steps.
- Descriptive key names — use clear names like
baseUrl,adminEmail,apiTimeoutrather than abbreviations. - Document your variables — maintain a consistent set of variable names across projects so team members know what to expect.
- Avoid hardcoded values in steps — if a value appears in multiple steps and might change, extract it into a variable.