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
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 the Cypress configuration file - 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 different ways to set environment variables. Each has a slightly different use case.
To summarize you can:
- Set in your configuration file
- Create a
cypress.env.json
- Export as
CYPRESS_*
- Pass in the CLI as
--env
- Set an environment variable within test configuration.
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
Cypress configuration under the env
key
will become an environment variable.
- cypress.config.js
- cypress.config.ts
const { defineConfig } = require('cypress')
module.exports = defineConfig({
projectId: '128076ed-9868-4e98-9cef-98dd8b705d75',
env: {
login_url: '/login',
products_url: '/products',
},
})
import { defineConfig } from 'cypress'
export default defineConfig({
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β
- Great for values that need to be checked into source control and remain the same on all machines.
- 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
Cypress configuration.
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β
- 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: '...' } }
.
- Another file you have to deal with.
- Overkill for 1 or 2 environment variables.
Option #3: CYPRESS_*
β
Any exported environment variables set on the command line or in your CI
provider that start with either CYPRESS_
or cypress_
will automatically be
parsed by Cypress.
The environment variable CYPRESS_INTERNAL_ENV
is reserved and should not be
set.
Overriding configuration optionsβ
Environment variables that match a corresponding configuration option will override any value set in the Cypress configuration.
Cypress automatically normalizes both the key and the value. The leading
CYPRESS_
or cypress_
is removed and the remaining name is camelCased, while
values are converted to Number
or Boolean
wherever possible.
For example, these environment variables in the command line will override any
viewportWidth
or viewportHeight
options set in the Cypress configuration:
export CYPRESS_VIEWPORT_WIDTH=800
export CYPRESS_VIEWPORT_HEIGHT=600
Overriding environment variablesβ
Environment variables that do not match configuration options will be set as
environment variables for use in tests with
Cypress.env()
, and will override any existing values
in the Cypress configuration env
object and cypress.env.json
files.
Cypress automatically removes the leading CYPRESS_
or cypress_
from any
environment variable name specified in this way.
For example, these environment variables in the command line:
export CYPRESS_HOST=laura.dev.local
export cypress_api_server=http://localhost:8888/api/v1/
Will yield these results inside a test file:
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:β
- Quickly export some values.
- Can be stored in your
bash_profile
. - Allows for dynamic values between different machines.
- Especially useful for CI environments.
- Not as obvious where values come from versus the other options.
- No support for nested fields.
Option #4: --env
β
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. In some shells, like Windows PowerShell, you may need to surround the key/value pair with quotes: --env "cyuser=dummyUser,cypassword=dummyPassword"
.
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 -β
- 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.
- Pain to write the
--env
options everywhere you use Cypress. - No support for nested fields.
Option #5: 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β
- End-to-End Test
- Component Test
// change environment variable for single suite of tests
describe(
'test against Spanish content',
{
env: {
language: 'es',
},
},
() => {
it('displays Spanish', () => {
cy.visit(`https://docs.cypress.io/${Cypress.env('language')}/`)
cy.contains('ΒΏPor quΓ© Cypress?')
})
}
)
// change environment variable for single suite of tests
describe(
'test against Spanish content',
{
env: {
language: 'es',
},
},
() => {
it('displays Spanish', () => {
cy.mount(<International lang={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β
- 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.