Keva161
Keva161

Reputation: 2683

How to dynamically generate test cases in Cypress?

I have a JSON file in while I store the test data needed for my Cypress tests but I would like to generate specific it blocks dynamically based on the contents of object keys/values (not every object has the same values or needs to perform the same steps).

So for example, if I have the following testData objects:

[
    {
        "name": "Do Something",
        "type": "A",
        
    },
    {
        "name": "Do Something",
        "type": "B",
        
    },
    {
        "name": "Do Something",
        "type": "C",
        
    },
]

Not all have the same type so will need to call upon different tests for their runs.

What is the best way to achieve this in Cypress? Is there a way that doesn't involve if/else blocks?

Upvotes: 5

Views: 10702

Answers (2)

Vadorequest
Vadorequest

Reputation: 17979

I wanted to do something similar. I went through all the links posted above and here are my findings:

What you're looking for is called "Dynamic tests".

Sometimes you want to iterate through a list of items, and for each item create a separate test. These tests are called dynamic tests. Examples of dynamic tests are:

  • run same test against different viewport resolutions
  • run same test against different sub-domains of your site
  • generate tests based on the fetched data

https://docs.cypress.io/examples/examples/tutorials.html#Best-Practices

Now, there are several ways of dealing with "dynamic data". I strongly advise to watch the talk of Brian Mann, author of Cypress. (2018, 27mn)

He speaks about the 3 different ways of dealing with dynamic data around 8:44.

Here is the summary:

enter image description here

Now, which strategy (or strategies, as they aren't mutually exclusive) you want to use depends on your constraints, it's up to you to decide.

By the way, I also strongly recommend going through Best Practices, there are many useful tips there. And luckily, one of the video example focuses on "Filters and data-driven tests" and uses the "Stub request" strategy.

You might be working with a React/Vue global data store (Redux, etc.), in such case there is a very simple trick for Cypress to access your store, as shown in the above video link.

enter image description here

The FAQ section "Can my tests interact with Redux / Vuex data store?" might also be useful. Also, "Is there any way to detect if my app is running under Cypress?" is good to know, and that's what the trick above is based upon.

Use case

Now, I'll take a concrete example, based on my personal needs.

I'm building a Multiple Single-Tenancy (MST) app where each "customer" has its own app. I'm running Cypress after my GitHub Actions has kicked and triggered a Vercel deployment. Once the app is deployed, that's where Cypress comes in.

The problem is, each customer has a different dataset, and each configuration might be slightly different from one another (multi languages, etc.). Thus, I cannot know upfront what tests I should run. For instance, testing if the "Change language" button is present in the footer doesn't make sense on a single-language customer, and will result in a failure.

Therefore, I need to run most of my tests dynamically.

After watching the above videos and reading through various resources, I was still hesitant regarding the "dynamic data strategy". Should I stub? Should I use the customer data somehow? (because I already fetches them)

There are pros/cons with each. For instance, if I stub, I can build various scenarios and test all of them. But I'd need to write a lot of hardcoded configuration and maintaining the tests would probably be boring and complicated. On the other hand, using the customer data would not allow me to test all potential scenarios.

Eventually, I figured that what I really need is to make sure the current customer platform works correctly. I don't care about testing everything, I just need to make sure it works for that customer. Eventually, I can write tests for all scenarios, but they'll be conditional, and only a handful will run for each customer. But that's not a big deal and it's much less hassle because I don't need to mock/stub anything, I can just use live data. Also, I won't get out-of-sync with the real data (unlike when mocking/stubbing), because that's what I use for real.

Upvotes: 7

Related Questions