Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixture data for tests #3963

Closed
robjensen82 opened this issue Apr 14, 2019 · 10 comments
Closed

Fixture data for tests #3963

robjensen82 opened this issue Apr 14, 2019 · 10 comments

Comments

@robjensen82
Copy link

robjensen82 commented Apr 14, 2019

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)
  })
})
@Lakitna
Copy link
Contributor

Lakitna commented Apr 15, 2019

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.

@must-git-good
Copy link

must-git-good commented Apr 15, 2019

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.

@Lakitna
Copy link
Contributor

Lakitna commented Apr 15, 2019

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.

@mateosilguero
Copy link

mateosilguero commented Apr 16, 2019

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

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

  it('...

@Lakitna
Copy link
Contributor

Lakitna commented Apr 16, 2019

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?

@robjensen82
Copy link
Author

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

@jennifer-shehane
Copy link
Member

Closing as resolved.

@MehranShafqat
Copy link

MehranShafqat commented May 12, 2020

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

@MarioPuzzo
Copy link

MarioPuzzo commented Dec 11, 2020

@Lakitna - had the same issue. so I added the JSON data in an array format.

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

`

then
const example = require('../../fixtures/users.json');
const demo = example.users

now you can use the demo forEach

@himsontam
Copy link

himsontam commented Nov 15, 2021

const someObject = require("../fixtures/URLParameterSignUpConfigs/URLParameterSignUpConfigs.json");

describe('URL Parameter Sign Up Test', () => {
it('Navigate to URL with Query String', () => {
cy.log(someObject.keyContactName);
});
});
image

Any idea why would that be?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants