📣 Join our Developer Experience Team on September 30th @ 2PM EDT/11AM PDT for an exclusive webcast on Cypress Patterns and Practices

Register

Environment Variables

Improve this doc


Difference between OS-level and Cypress environment variables

In Cypress, “environment variables” are variables that are accessible via Cypress.env. These are not the same as OS-level environment variables. However, it is possible to set Cypress environment variables from OS-level environment variables.


Environment variables are useful when:

  • Values are different across developer machines.
  • Values are different across multiple environments: (dev, staging, qa, prod)
  • Values change frequently and are highly dynamic.

Environment variables can be changed easily - especially when running in CI.

Instead of hard coding this in your tests:

cy.request('https://api.acme.corp') // this will break on other environments

We can move this into a Cypress environment variable:

cy.request(Cypress.env('EXTERNAL_API')) // points to a dynamic env var
Using ‘baseUrl’

Environment variables are great at pointing to external services and servers, or storing password or other credentials.

However, you do not need to use environment variables to point to the origin and domain under test. Use baseUrl instead of environment variables.

cy.visit() and cy.request() are automatically prefixed with this value - avoiding the need to specify them.

baseUrl can be set in your configuration file (cypress.json by default) - and then you can set an environment variable in your OS to override it like shown below.

CYPRESS_BASE_URL=https://staging.app.com cypress run

Setting

There are 5 different ways to set environment variables. Each has a slightly different use case.

To summarize you can:

Don’t feel obligated to pick just one method. It is common to use one strategy for local development but another when running in CI.

When your tests are running, you can use the Cypress.env function to access the values of your environment variables.

Option #1: configuration file

Any key/value you set in your configuration file (cypress.json by default) under the env key will become an environment variable.

{
  "projectId": "128076ed-9868-4e98-9cef-98dd8b705d75",
  "env": {
    "login_url": "/login",
    "products_url": "/products",
  }
}

Test file

Cypress.env()               // {login_url: '/login', products_url: '/products'}
Cypress.env('login_url')    // '/login'
Cypress.env('products_url') // '/products'

Overview

Benefits
  • Great for values that need to be checked into source control and remain the same on all machines.
Downsides
  • Only works for values that should be the same on across all machines.

Option #2: cypress.env.json

You can create your own cypress.env.json file that Cypress will automatically check. Values in here will overwrite conflicting environment variables in your configuration file (cypress.json by default).

This strategy is useful because if you add cypress.env.json to your .gitignore file, the values in here can be different for each developer machine.

{
  "host": "veronica.dev.local",
  "api_server": "http://localhost:8888/api/v1/"
}

From test file

Cypress.env()             // {host: 'veronica.dev.local', api_server: 'http://localhost:8888/api/v1'}
Cypress.env('host')       // 'veronica.dev.local'
Cypress.env('api_server') // 'http://localhost:8888/api/v1/'

An Overview

Benefits
  • Dedicated file just for environment variables.
  • Enables you to generate this file from other build processes.
  • Values can be different on each machine (if not checked into source control).
  • Supports nested fields (objects), e.g. { testUser: { name: '...', email: '...' } }.
Downsides
  • Another file you have to deal with.
  • Overkill for 1 or 2 environment variables.

Option #3: CYPRESS_*

Any OS-level environment variable on your machine that starts with either CYPRESS_ or cypress_ will automatically be added to Cypress’ environment variables and made available to you.

Conflicting values will override values from your configuration file (cypress.json by default) and cypress.env.json files.

Cypress will strip off the CYPRESS_ when adding your environment variables.

The environment variable CYPRESS_INTERNAL_ENV is reserved and should not be set.

Export cypress env variables from the command line

export CYPRESS_HOST=laura.dev.local
export cypress_api_server=http://localhost:8888/api/v1/

In test file

In your test file you should omit CYPRESS_ or cypress_ prefix

Cypress.env()             // {HOST: 'laura.dev.local', api_server: 'http://localhost:8888/api/v1'}
Cypress.env('HOST')       // 'laura.dev.local'
Cypress.env('api_server') // 'http://localhost:8888/api/v1/'

Overview:

Benefits
  • Quickly export some values.
  • Can be stored in your bash_profile.
  • Allows for dynamic values between different machines.
  • Especially useful for CI environments.
Downsides
  • Not as obvious where values come from versus the other options.
  • No support for nested fields.

Option #4: --env

Lastly you can pass in environment variables as options when using the CLI tool.

Values here will overwrite all other conflicting environment variables.

You can use the --env argument for cypress run.

Multiple values must be separated by a comma, not a space.

From the command line or CI

cypress run --env host=kevin.dev.local,api_server=http://localhost:8888/api/v1

Test file:

Cypress.env()             // {host: 'kevin.dev.local', api_server: 'http://localhost:8888/api/v1'}
Cypress.env('host')       // 'kevin.dev.local'
Cypress.env('api_server') // 'http://localhost:8888/api/v1/'

Overview -

Benefits
  • Does not require any changes to files or configuration.
  • More clear where environment variables come from.
  • Allows for dynamic values between different machines.
  • Overwrites all other forms of setting env variables.
Downsides
  • Pain to write the --env options everywhere you use Cypress.
  • No support for nested fields.

Option #5: Plugins

Instead of setting environment variables in a file, you can use plugins to dynamically set them with Node code. This enables you to do things like use fs and read off configuration values and dynamically change them.

We’ve fully documented how to do this here.

Overview

Benefits
  • Most amount of flexibility
  • Ability to manage configuration however you’d like
Downsides
  • Requires knowledge of writing in Node
  • More challenging

Option #6: Test Configuration

You can set environment variables for specific suites or tests by passing the env values to the test configuration.

Suite of test configuration

// change environment variable for single suite of tests
describe('test against Spanish site', {
  env: {
    language: 'es'
  }
}, () => {
  it('displays Spanish', () => {
    cy.visit(`https://docs.cypress.io/${Cypress.env('language')}/`)
    cy.contains('¿Por qué Cypress?')
  })
})

Single test configuration

// change environment variable for single test
it('smoke test develop api', {
  env: {
    api: 'https://dev.myapi.com'
  }
}, () => {
  cy.request(Cypress.env('api')).its('status').should('eq', 200)
})

// change environment variable for single test
it('smoke test staging api', {
  env: {
    api: 'https://staging.myapi.com'
  }
}, () => {
  cy.request(Cypress.env('api')).its('status').should('eq', 200)
})

Overview

Benefits
  • Only takes effect for duration of suite or test.
  • More clear where environment variables come from.
  • Allows for dynamic values between tests

Overriding Configuration

If your environment variables match a standard configuration key, then instead of setting an environment variable they will instead override the configuration value.

Change the baseUrl configuration value / not set env var in Cypress.env()

export CYPRESS_BASE_URL=http://localhost:8080

‘foo’ does not match config / sets env var in Cypress.env()

export CYPRESS_FOO=bar

You can read more about how environment variables can change configuration here.

See also