How to run your Cypress tests in multiple environments

Cypress as a testing tool is flexible in the sense that we can use it for mocking HTTP response, re-create complex user interactions as well as monitoring, and responding to network requests.

Plus, it’s written in JavaScript!

This may or may not be a plus for some. But considering it’s the de facto language of the web at the moment. It means that one language can be used for the web application stack. And powering your testing solution and enabling seamless collaboration with developers, testers, and even technology savvy stakeholders.

YAY, JavaScript

Just as a side note, these are not reasons alone to choose Cypress over another test automation tool. I have written before on the topic and advocate using the right tool to get your job done. But seeing as this is a blog post on Cypress, I’m going to assume you have already made that decision and want to find out more on how to use a single code base for testing across your multiple environments. So let’s keep going.

One code base to rule them all

You are most likely already running your tests in one environment, one which is dedicated to testing or QA activities that is separate from your development environment and your client-facing production website.

I’m also going to assume that you are already using baseUrl in your cypress.json to configure which website your tests are running on.

If you are not making use of the baseUrl feature the Cypress provides, then it allows you to specify the prefix that is used with a cy.visit() or cy.request() command. Instead of typing out cy.visit(‘https://google.co.uk) for example.

With the baseUrl set within cypress.json as below:

{
    “baseUrl”: “https://google.co.uk”
}

You only need to make use of cy.visit(‘/’) to replicate the same results you were getting before. Pretty cool, huh?

But what if we want to run tests on another environment?

Using baseUrl within your main cypress.json is fine. But what if you want to switch environments as required and run your tests with no manual intervention and editing?

You really don’t want to make configuration changes whenever you get asked or need to run your integration tests on another URL. Not only is this tedious, but it means your test automation isn’t robust, lacks the use of best practises and makes things harder to maintain.

Luckily Cypress provides a solution to this problem that is elegant to use and with the help of JavaScript, powerful!

Custom configurations

If you want to use variable’s interchangeably in your solution, then it makes sense that you need to make use of multiple custom configuration files. Not only does this allow you to have a distinct separation between the options needed for each of your testing environments. It also enables rapid switching between each one with no complex configuration changes or editing that may be forgotten about when passing the solution over to a new member of your testing team.

What I would recommend doing is creating a dedicated config directory within your cypress folder and storing your custom configuration files within there.

cypress/config/qa.json
cypress/config/testing.json

Each of these would hold their own baseUrl variable and we would call each one using environment flags so that Cypress knows which one to use.

But we’re getting ahead of ourselves. We first need a way for Cypress to understand that these new files are configuration files. And that can be achieved by using the following plugin code below. I have written about plugins before as a solution to generate test data. But we can use plugins in Cypress for a multitude of reasons and they are one feature that stands out in Cypress’s arsenal.

Paste the below in your plugins/index.js file.

const path = require(“path”);
const fs = require(“fs-extra”);

module.exports = (on, config) => {
    
    function getConfigurationByFile(file) {
        const pathToConfigFile = path.resolve(“cypress/config”, `${file}.json`);

        return fs.readJson(pathToConfigFile);
    }
    const file = config.env.configFile || “qa”;

    return getConfigurationByFile(file);
};

To give a brief description of what the above is doing. It’s essentially informing Cypress that the files within the config directory are valid Cypress configuration files and if one is passed in the environment flag at run time, Is it OK to use it. Or if one isn’t specified, use the qa.json file instead.

Note: If you are going to use the above code. Make sure that you install both the path module, and fs as well and save them to your dev dependencies.

Putting it all together

The last step of the process is to actually run Cypress with your desired configuration file. To do this, I would recommend adding a new line into the scripts section of your your package.json file which will take away the need to write in a long command every time you want to switch between your environments.

“scripts”: {
        “cy:open:qa”: “cypress open --env configFile=qa”,
        “cy:run:qa”: “cypress run --env configFile=qa”,
    }

If you are using VSCode. All you need to do is click on the command to run it, and you are testing on a new environment!

I hope you found this post useful. If you have a question or would like to get in contact. You can reach me on LinkedIn, Twitter, or via my contact form.

Posted by Kevin Tuck

Kevin Tuck is an ISTQB qualified software tester with nearly a decade of professional experience. Well versed in creating versatile and effective testing strategies. He offers a variety of collaborative software testing services. From managing your testing strategy, creating valuable automation assets, or serving as an additional resource.

Leave a Reply