Testing lists of items

April 6th, 2020
4 min read

TL;DR:

  • you can test your lists using .then() or .each()
  • Cypress retries can help you test changes in your app
  • you can pass a function to .should() command

You can try out all the examples in this blog by cloning my repo. The app is there too.

Hello everyone 👋 We are going to test a list of todo items today. In my job as QA in Slido, I test lists a lot. In this blog I’m sharing some of my tips on how to that.

We can start by testing a list with two items. In a situation where we test a couple of items, the testing flow can be pretty straightforward. In our first test, we use .get() to select our todo items and then .eq() to filter the item we want to work with. Code looks something like this:

Copy to clipboard
undefined

![selecting_each_item_individually.mp4](Selecting each item individually)

We can make this code more compact. Instead of selecting each element individually, we can select them both and make a single assertion using .then(). When .get() command finds multiple elements it returns an array. This means we can reference each item as we would in an array, using itemsi where i is the index number.

Copy to clipboard
undefined

![selecting_both_items_and_making_a_single_assertion.mp4](Selecting both items and making a single assertion)

Testing longer lists

While this approach is nice, we might get into a situation where want to test longer lists. With 10 or more items, our code might get repetitive. So instead, we can select our todo items, and then use .each() command. This command works very similarly to a array.forEach() function and it enables us to work with items that are yielded via .get() command.

Copy to clipboard
undefined

![testing_a_longer_todo_list_using_each_command.mp4](Testing a longer todo list using .each() command)

Checking position of a certain todo item

Now let’s say, we want to check an item being on a first position, but our test starts with a different state. Imagine this is a live collaborative todo list and that we want to test a scenario where another user changes the todo list.

Here we have a test, that should have an item with the text „wash dishes“ on a first position. Our test starts with the item on second position, and during the test, we delete the first item.

Copy to clipboard
undefined

![failed_test.mp4](Failed test)

But this test fails! The reason is that Cypress’ automatic retries don’t query the whole command chain, only the last command. In other words, our .eq(0) is retried, but our .get('.todo') command is not. This means we are stuck with 3 todo items even after we delete the first one. See how the little blue “number 3" does not change after we delete the first todo item. There is a great article about this in Cypress documentation. To solve this problem, we can add an assertion for the length after our .get('.todo') command, so that we first assert the correct number of todo items and then assert the text of the first one.

Copy to clipboard
undefined

![our_test_moves_to_next_command_only_after_assertion_passes.mp4](Our test moves to next command only after assertion passes)

This solution is not really satisfying, is it? We may be facing a situation where the number of our items does not change, but only the order of our items changes. Because we can use drag and drop in our app 😎. In that case, we can use .should() command and pass a function into it. There are many cool examples in the documentation on this. The final code looks very similar to when we are using .then(). The main difference is, that .should() commands uses retries logic, but .then() not use retry.

Copy to clipboard
undefined

![passing_test.mp4](Passing test)

That’s it. Hope you enjoyed this.

Let’s keep in touch

From time to I send some useful tips to your inbox and let you know about upcoming events. Sign up if you want to stay in loop.

is required.

I treat your email address like I would my own. That means no ads. Just notifications of when I do cool stuff. Unsubscribe anytime. Click here to read about how I handle your data