Test Variations of a Feature in Cypress with a data-driven Test

Andy Van Slaars
InstructorAndy Van Slaars

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 3 years ago

Many applications have features that can be used with slight variations. Instead of maintaining multiple tests with nearly identical code, we can take advantage of the JavaScript runtime and use normal data structures and plain old JavaScript to test and make assertions for multiple interactions in a single test.

Instructor: [00:00] I've created an inspect file for the footer. We're going to test that our footer links filter our to-dos. To do this, we're going to need to create a new fixture with data that has mixed to-dos, some that are done, some that are not.

[00:12] Under Cypress, I'll expand out the fixtures directory. I'm going to open todos.json. I'm going to copy this, and I'm going to create a new file under fixtures. I'm going to call this mixed_todos.json.

[00:25] In this file, I'm going to paste those to-dos, and I'm going to toggle to-dos two and three to be complete. I'll save that, and back [inaudible] back. We're going to start our test.

[00:42] The first thing we're going to do is we're going to use cy.seedandvisit to run that custom command we created. We want to pass it different seed data from the default.

[00:51] I'm going to give it the string, fixture:mixed_todos. Now, when this stubs out our initial API call to load the to-dos into the app, it's going to use our mixed to-dos fixture file that we just created.

[01:08] Let's verify this works. I'm going to save this test, and I'll load up the Cypress UI. I'm going to find my footer spec file and run. As we can see, we have two active items and two completed items.

[01:26] Let's switch back to the code and write our test. I'm going to start with the side.contains command, and I'm going to find the element that contains the word active. This should give us our active link in the footer.

[01:40] I'm going to click it, I'm going to save this test, switch back to the runner, and just verify that that's working. We'll see that our active link was found, and the click worked. Nothing has failed, no errors.

[01:52] If we look at the preview, we'll see that it's actually doing what we expect. Now we just have to write our assertion. From here, we're going to drop down, and we'll throw in a cy.get.

[02:02] We're going to get our to-do list, LIs, and we're going to say that they should have a length of two. There's about two items remaining in our list.

[02:17] We can save this, switch back to the runner, and everything's working as expected. We have a passing test for our active link, we have two other links in the footer. We could duplicate this test and click on different links and make different assertions, but we're essentially running the same task three times with slightly different parameters.

[02:37] Instead, we can use some simple data to drive this test, and test all three links in the same test. I'm going to start at the top of the test, I'm going to define a constant which I'll call filters.

[02:48] Filters is just going to be an array of objects, and each object is going to get a link property. That's going to represent the text of the link we want to click, and we're going to give it an expected length property.

[03:01] That's going to be the number of items we expect in the list after clicking that link. I'll create two more of these, and we'll just update the link text. We're going to have a completed link, and we're going to have an all link.

[03:16] The completed length will be two and the all length should be four. Now, I'm going to drop down under SeedAndVisit, and I'm going to call cy.wrap. Wrap is going to take in our filters object and put that in the context of a Cypress command.

[03:31] We can chain on the Cypress each method, which is going to take a function that will receive our individual filters, and it's going to loop through them. I'm going to take our cy.contains with our click, our cy.get with our assertion, and I'll move those up into the each.

[03:47] Now, I'm going to replace this active string with filter.link. I'm going to replace the number in our assertion here to filter.expectedlength. I'm going to save this and I'll switch back to the runner.

[04:04] We'll see that our single test is going to run and test each one of our links individually.

Hoang
Hoang
~ 4 years ago

why can't we just loop through the values of the filters array ? what's the purpose of the cy.wrap function

filters.forEach(filter => {
    cy.contains(filter.link).click()

    cy.get('.todo-list li').should('have.length', filter.expectedLength)
})
Pavel Klochkov
Pavel Klochkov
~ 3 years ago

There is the misprint in the transcription in block 03:47. In the code at line 11. You have .each(filters => { instead of .each(filter => {