Michael Lynch
Michael Lynch

Reputation: 3139

How should you structure CRUD cypress tests?

I'm working on a React app and our team is writing Cypress tests for it. We want to test basic CRUD functionality, so we have created three tests:

The CREATE test uses a fixture to define the new user.

The UPDATE and DELETE tests reference that same fixture and update and delete the user that was created in the previous test. This means the UPDATE and DELETE tests are dependent on the CREATE test. Is this ok?

Based on what I'm reading, it sounds like each Cypress test should be able to run independently and I can see that's not the case here.

However, what is the best way to do that?

I don't think it makes sense to copy and paste the same 10-20 lines of code from the CREATE test and duplicate them in both the UPDATE and DELETE tests. Is there a way we can abstract the CREATE test and include it in the UPDATE and DELETE tests?

Or should we just combine all three tests into a single "CRUD user" test?

Upvotes: 5

Views: 1026

Answers (1)

pavelsaman
pavelsaman

Reputation: 8322

Based on what I'm reading, it sounds like each Cypress test should be able to run independently.

Ideally, yes. There are several reasons for that:

  • in theory, if one test fails, the other ones can still pass; but if your test that creates some entity (user in your case) fails, the other ones will fail for sure, but not because of what they focus on
  • you don't really have a way to ensure the tests will be executed in the same order; although in Cypress I think it's based on alphabetical order, but this might not apply with other tools or even with Cypress in the future; or you decide to add some test somewhere which changes the order of tests and all of a sudden some tests will fail and you won't instantly know why

I don't think it makes sense to copy and paste the same 10-20 lines of code from the CREATE test and duplicate them in both the UPDATE and DELETE tests. Is there a way we can abstract the CREATE test and include it in the UPDATE and DELETE tests?

Cypress offers for example commands, so your final test code can look like this:

it('CREATE user', () => {
  cy
    .fixture('user')
    .then(user => {
      cy
        .createUser(user)
        // whatever checks you need to perform here
        .its('response.statusCode')
        .should('eq', 201); 
    });
});

then if your 10-20 lines of code are hidden behind cy.createUser(), you can easily reuse that in other tests:

it('DELETE user', () => {
  cy
    .fixture('anotherUser')
    .then(anotherUser => {
      cy
        .createUser(anotherUser)
        .then(response => {
          cy
            .deleteUser(response.body.id)
            // whatever checks you need to perform
            .its('response.statusCode')
            .should('eq', 204);
        });
    });
});

I think such code reads quite easily and the tests are short as well, so it is easily maintained if need be.

Upvotes: 2

Related Questions