Skip to content
Advertisement

Keep dynamic variables between tests in Cypress

I am trying to do a Cypress test where I want to set in an input a random number and after that check that random number is set ok in another page. I’m creating the random number with this function:

function getRandomArbitrary(min, max, decimals) {
  return (Math.random() * (max - min) + min).toFixed(decimals);
}

And setting the variables inside the describe like:

  describe('Reflect changes from X to the Y', () => {
  const termCap = getRandomArbitrary(0.01, 0.3, 2);
  const termCapFee = getRandomArbitrary(0.01, 0.3, 2);

The issue I’m currently having is that the variables reset in every different it() I create. And I don’t what to happen as I want to be the same consistent number through all the tests.

I’ve tried setting them in a before() but that didn’t work either.

Does anyone know how should I create the variables?

Advertisement

Answer

I’ve tried setting them in a before() but that didn’t work either.

The before block should work. Maybe the before block isn’t setup properly? I’m able to get this to work using the following setup.

describe("Foo Fighter", function() {
    var foo;
    before(function () {
        foo = getRandomArbitrary(1,10,1);
    });

    it("Fighting foo 1", function () {
        cy.log(foo);
    });
    it("Fighting foo 2", function () {
        cy.log(foo);
    });
    it("Fighting foo 3", function () {
        cy.log(foo);
    });
});
function getRandomArbitrary(min, max, decimals) {
  return (Math.random() * (max - min) + min).toFixed(decimals);
}

Which produces the following result, the random number staying the same during each it block.

Test run

The logic flow goes:

  • In the describe block, declare your variable.
  • In the before block, set your variable using the random number.
  • In the it block, use the set variable.

EDIT:

To answer your comment:

If I set it like you it works fine, but imagine if in the first it you visit google, and in the second it you visit github, the before block will run twice

The issue here is that when you visit a new site, Cypress reloads the entire test context, so a before block, like you mentioned, will be run again each time the test context is reloaded (i.e. each time a new domain is visited).

The way around this is to cheat by setting up another describe that runs first and writing your variables to fixtures and using those fixtures in your test, like so:

describe("Before Describe", function(){
    const foo = getRandomArbitrary(1,10,1);
    it("Setting up test context", function() {
        cy.writeFile("cypress/fixtures/test.json", { "foo" : foo});
    });
});



describe("Foo Fighter", function() {
    it("Fighting foo 1", function () {
        cy.visit("https://example.cypress.io");
        cy.fixture("test.json").then(kung => {
            cy.log(kung.foo);
        })
    });
    it("Fighting foo 2", function () {
        cy.visit("https://google.com")
        cy.fixture("test.json").then(kung => {
            cy.log(kung.foo);
        })
    });
    it("Fighting foo 3", function () {
        cy.fixture("test.json").then(kung => {
            cy.log(kung.foo);
        })
    });
});

function getRandomArbitrary(min, max, decimals) {
  return (Math.random() * (max - min) + min).toFixed(decimals);
}

This will produce the following results:

Test two

Admittedly, not the cleanest way to construct your testing flow, however, it produces the result you’re after. Should also work if you put the setup in an it that comes first within the same describe as the other tests.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement