How to Loop over Jest Unit Tests
Tags: jest, javascript
Published: 2022-09-27 10:07:14

---
title: How to Loop over Jest Unit Tests
published: true
date: 2022-09-26 21:33:43 UTC
tags: Jest,JS
canonical_url: https://robertmarshall.dev/blog/how-to-loop-in-jest-unit-tests/
---
--------

This article was originally posted (and is more up to date) at https://robertmarshall.dev/blog/how-to-loop-in-jest-unit-tests/

--------

Sometimes when writing Jest unit tests you are going to want to be able to loop over items to quickly test different cases. Whether this be looping over an array of items, or counting between numbers in your Jest Test. This will massively simplify your Jest test suite.

There are a number of ways to do this. This post aims to outline the ways that I have looped through Jest tests in the past.

## Looping over tests with Jest.Each

For very basic repetitive Jest tests I would use `jest.each`. It allows you to keep duplicating the same test with different data. You can write the test once and let the data do the work.

### Using Basic Arrays and printf

An example of this is:

```javascript
test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
  expect(a + b).toBe(expected);
});
```

The above code is taking in a set of data within an array, The name of the test using printf to inject parameters into the text, and the arguments to be passed into the test itself.

For more information about `jest.each` take a look at the [Jest documentation](https://jestjs.io/docs/api#testeachtablename-fn-timeout).

### Using Array of Objects

Rather than using printf, you can pass in an array of objects and reference them using string literals. Like so:

```javascript
test.each([
  {a: 1, b: 1, expected: 2},
  {a: 1, b: 2, expected: 3},
  {a: 2, b: 1, expected: 3},
])('.add($a, $b)', ({a, b, expected}) => {
  expect(a + b).toBe(expected);
});
```

I personally prefer this. It is more explicit in what each item is, and allows you to build a more complex test data set.

## Using Jest.Each with a Table

The `jest.each` API also lets you pass data into it in a more ‘visual’ way. Using one large string literal you can shape the data in a table.

This looks like:

```javascript
test.each`
  a | b | expected
  ${1} | ${1} | ${2}
  ${1} | ${2} | ${3}
  ${2} | ${1} | ${3}
`('returns $expected when $a is added $b', ({a, b, expected}) => {
  expect(a + b).toBe(expected);
});
```

The first row sets up the table headings, and the rest of the rows using template literals to add the values. Then the test title itself using template literals to inject the data into the string.

Not my top choice, but some people like this way of handling the tests.

## Using a For Loop in Jest Tests

The for loop is my go to when wanting to dynamically loop through Jest tests. In this way of writing loops in jest there is no need for the printf variable injection. Call me old fashioned (or wrong), but I also like the flexibility of being able to fully control the tests, and how they are created.

For example, the `for` loop approach allows me to loop `describe` jest test blocks, as well as the unit tests inside. However with this freedom comes the need to restrict yourself. Otherwise the tests could become to over-engineered and end up being too confusing.

Simple tests are better.

```javascript
const testData = [
    { a: 1, b: 1, expected: 2 },
    { a: 1, b: 2, expected: 3 },
    { a: 2, b: 1, expected: 3 }
];

for (let i = 0; i < testData.length; i += 1) { it(`.add(${testData[i].a}, ${testData[i].b})`, () => {
        expect(testData[i].a + testData[i].b).toBe(testData[i].expected);
    });
}
```

The above shows how the for loop would be used to create dynamically generated Jest tests. However it should be used sparingly, and the `jest.each` will be able to handle most situations. The `for` loop is really more for complex situations.

 

For more Jest hints and tips take a look at the [Jest Testing Category](https://robertmarshall.dev/blog/category/jest/)!

Hopefully this helped you, and if you have any questions you can reach me at: [@robertmars](https://twitter.com/robertmars)