Configuring Cypress for multiple testing environments
Tags: engineeringmonday, javascript, testing
Published: 2020-02-17 08:18:35

---
title: Configuring Cypress for multiple testing environments
published: true
description: A guide on how to setup Cypress for integration, e2e and storybook tests
tags: engineeringmonday, javascript, testing
canonical_url: https://www.bornfight.com/blog/how-to-configure-cypress-for-multiple-testing-environments/
---

[Cypress](https://www.cypress.io/) is a great tool for front-end testing. It provides features such as mocking HTTP responses, stubbing objects and methods and simulating user interaction. 

It can be used as a fully-fledged front-end testing framework for unit, integration and e2e tests. This post assumes you are already somewhat familiar with Cypress and its methodologies, and it serves as a guide for advanced configuration which can help you structure and organize your tests. So, let's get straight to the point.

When first [installing and running Cypress with npm or yarn](https://docs.cypress.io/guides/getting-started/installing-cypress.html#Opening-Cypress), it will generate some default tests and configuration for you. 

At the time of writing, these files and directories are:

```javascript
// configuration
./cypress.json 

// directories with respective files / tests
./cypress/fixtures/ 
./cypress/integration/examples/
./cypress/plugins/
./cypress/support/
```
The default command for running Cypress in interactive mode is `./node_modules/.bin/cypress open` and it will by default use `cypress.json` as a configuration file.

An example of a configuration file:

```json
{
    "baseUrl": "http://localhost:3000",
    "integrationFolder": "cypress/integration",
}
```
Cypress will also by default run all tests from the `integration` directory, supporting nested directories. We could add all our unit, integration and e2e tests to the `integration` directory, but we want to configure some things differently, depending on our environment. For example, we could avoid some API calls from the app by completely blocking the host from the configuration file.

Let's say we want to mock the response for the `foo` resource from our API. In our Cypress test, we'll do something like this:

```javascript
describe("foo", () => {
    it("should fetch and render foo", () => {
      cy.server();
      // load fixture and mock response
      cy.fixture("foo").then((response) => {
        cy.route({
          method: "GET",
          // you can also setup base url in cypress config
          // it can be used as Cypress.env('BASE_API_URL')
          url: "https://api.my-app.com/foo/**",
          response: response,
        });
     });
     // ...rest of the test
}));
```

By specifying the same host of our backend API in blacklistHosts, Cypress will allow creating mock responses for the blocked domain, but it will intercept and disallow any other response to that same domain. This could be a handy setup for integration testing, where you want to test a feature in a very specific scenario, mocking all the requests and data the application needs. This is a powerful configuration, but for e2e tests, we don't want to block the real API because we need to test front-end with the real back-end services. Therefore, we need to split our configs.


We'll first create a `cypress-integration.json` file and place it inside auto-generated `cypress` directory. Then, we specify another path for the location of the tests. For our use-case, that is `cypress/tests/integration`. Notice the change from `integration` to `tests` naming. The naming is not needed to be replicated; feel free to use directory names which suit you and your team.


Example `cypress-integration.json` file:
```json
{
    "baseUrl": "http://localhost:3000",
    "integrationFolder": "cypress/tests/integration",
    "blacklistHosts": ["api.my-app.com"]
}
```
Now, to run only those tests suites for integration tests, we need to add commands in our `package.json`. `"cypress:open:integration"` is for "interactive" mode, and `cypress:run:integration` is for running in "CI" mode.

```json
{
 "scripts": {
   "cypress:open:integration": "cypress open --config-file cypress/cypress-integration.json",
   "cypress:run:integration": "cypress run --config-file cypress/cypress-integration.json"
 }
}
```
Now, you can repeat this process for other environments, such as e2e, storybook or unit tests, and provide different configurations for them. 🚀


Thank you for reading! 🙏