Cypress: Fixture data for tests

Created on 14 Apr 2019  路  8Comments  路  Source: cypress-io/cypress

Current behavior:

const names = ['foo', 'bar', 'baz']

names.forEach(name => {
  it(`works for ${name}`, () => {
     cy.visit('...')
     cy.contains(name)
  })
})

Desired behavior:

It would be extremely useful to be able to drive tests out of fixture data. That way if you want to reuse the same data in a different test you don't need to duplicate it. Possibly like this:

const names = cy.fixture('foo/examples');

names.forEach(name => {
  it(`works for ${name}`, () => {
     cy.visit('...')
     cy.contains(name)
  })
})

Most helpful comment

To recap for posterity: There are three reliable ways to do this:

The examples below expect the fixture file to contain an array.

.fixture() inside an it
The Cypress chain in the example cannot be executed outside an it block.

describe('Using `.fixture()` in `it` block', function() {
    it('gets its data from a fixture', function() {
        cy.fixture('foo/examples')
            .then((examples) => {
                // `examples` contains the full contents of the fixture
                examples.forEach((example) => {
                    // Do something with each example
                });
            });
    });
});

.fixture inside a before or beforeEach
The Cypress chain in the example cannot be executed outside a before/beforeEach block.

describe('Using `.fixture()` in `before` block', function() {
    before(function() {
        cy.fixture('foo/examples')
            .as('fooExamples');
    });

    it('gets its data from a fixture', function() {
        cy.get('@fooExamples')
            .then((examples) => {
                // `examples` contains the full contents of the fixture
                examples.forEach((example) => {
                    // Do something with each example
                });
            });
    });
});

Using require
Note that you can use this method to dynamically generate tests by swapping lines 4 and 5. If you don't know what this means I suggest you simply try it to see what happens.

const examples = require('../../fixtures/foo/examples');
// `examples` contains the full contents of the fixture

describe('Using `require`', function() {
    it('gets its data from a fixture', function() {
        examples.forEach((example) => {
            // Do something with each example
        });
    });
});

Does anyone have anything to add?

All 8 comments

Right now there are two ways to do this:

Using .fixture()

cy.fixture('foo/examples')
  .then((names) => {
    names.forEach(name => {
      it(`works for ${name}`, () => {
        cy.visit('...')
        cy.contains(name)
      })
    })
})

Using node's require

const names = require('../../fixtures/foo/examples');

names.forEach(name => {
  it(`works for ${name}`, () => {
    cy.visit('...')
    cy.contains(name)
  })
})

I think these options are enough, but please change my mind if you disagree.

For a bit of additional clarity, please recall that cy.fixture (which in many cases is the 'easiest' answer here) will only work inside the context of a running test. (Inside the 'it' statement, not before).

If OP wants to most closely follow the format he's presented, he will want to require his content in, instead. (Which might take more work/abstraction than is ideal, depending on the format, the amount of fixtures already in place, etc.) Nevertheless, I do agree that the current solutions are probably sufficient.

Good catch, I did not realise that you can't use .fixture() outside of an it but it makes sense you can't do that.

I can use cy.fixture inside the before/beforeEach statement:

describe('Test', function() {
  beforeEach(() => {
    cy.fixture('user.json').as('user');
  });

  it('...

To recap for posterity: There are three reliable ways to do this:

The examples below expect the fixture file to contain an array.

.fixture() inside an it
The Cypress chain in the example cannot be executed outside an it block.

describe('Using `.fixture()` in `it` block', function() {
    it('gets its data from a fixture', function() {
        cy.fixture('foo/examples')
            .then((examples) => {
                // `examples` contains the full contents of the fixture
                examples.forEach((example) => {
                    // Do something with each example
                });
            });
    });
});

.fixture inside a before or beforeEach
The Cypress chain in the example cannot be executed outside a before/beforeEach block.

describe('Using `.fixture()` in `before` block', function() {
    before(function() {
        cy.fixture('foo/examples')
            .as('fooExamples');
    });

    it('gets its data from a fixture', function() {
        cy.get('@fooExamples')
            .then((examples) => {
                // `examples` contains the full contents of the fixture
                examples.forEach((example) => {
                    // Do something with each example
                });
            });
    });
});

Using require
Note that you can use this method to dynamically generate tests by swapping lines 4 and 5. If you don't know what this means I suggest you simply try it to see what happens.

const examples = require('../../fixtures/foo/examples');
// `examples` contains the full contents of the fixture

describe('Using `require`', function() {
    it('gets its data from a fixture', function() {
        examples.forEach((example) => {
            // Do something with each example
        });
    });
});

Does anyone have anything to add?

Thanks for taking the time to comment. For my use case I found using require was useful. The idea I had came from using PHPUnit and data providers

Closing as resolved.

To recap for posterity: There are three reliable ways to do this:

The examples below expect the fixture file to contain an array.

.fixture() inside an it
The Cypress chain in the example cannot be executed outside an it block.

describe('Using `.fixture()` in `it` block', function() {
    it('gets its data from a fixture', function() {
        cy.fixture('foo/examples')
            .then((examples) => {
                // `examples` contains the full contents of the fixture
                examples.forEach((example) => {
                    // Do something with each example
                });
            });
    });
});

.fixture inside a before or beforeEach
The Cypress chain in the example cannot be executed outside a before/beforeEach block.

describe('Using `.fixture()` in `before` block', function() {
    before(function() {
        cy.fixture('foo/examples')
            .as('fooExamples');
    });

    it('gets its data from a fixture', function() {
        cy.get('@fooExamples')
            .then((examples) => {
                // `examples` contains the full contents of the fixture
                examples.forEach((example) => {
                    // Do something with each example
                });
            });
    });
});

Using require
Note that you can use this method to dynamically generate tests by swapping lines 4 and 5. If you don't know what this means I suggest you simply try it to see what happens.

const examples = require('../../fixtures/foo/examples');
// `examples` contains the full contents of the fixture

describe('Using `require`', function() {
    it('gets its data from a fixture', function() {
        examples.forEach((example) => {
            // Do something with each example
        });
    });
});

Does anyone have anything to add?

@Lakitna Lakitna
My problem is I dont have any array I have json data like this

{
    "sn1": {
        "name": "fname",
        "details": {
            "id": 1,
            "role": "tester"
        },
        "gender": "male"
    },
    "sn2": {
        "name": "fname",
        "details": {
            "id": 1,
            "role": "tester"
        },
        "gender": "male"
    }
}

How I can achieve on this please

Was this page helpful?
0 / 5 - 0 ratings

Related issues

simonhaenisch picture simonhaenisch  路  3Comments

weskor picture weskor  路  3Comments

jennifer-shehane picture jennifer-shehane  路  3Comments

jennifer-shehane picture jennifer-shehane  路  3Comments

tahayk picture tahayk  路  3Comments