Testing

Now that we have a working application, we must ensure it keeps working as we add new features. This is where testing comes in. Testing is a way to make sure that our code is working as expected. It is a way to ensure we keep functionality intact when adding new features.

We will use Jest to test our React application since it's a widespread tool. Jest is a testing framework focusing on simplicity. It is straightforward to use, and it has a lot of features.

Unit testing

As the name suggests, unit testing is a way to test a single unit of code. This unit can be a function, a class, a component, etc. The goal of unit testing is to make sure that the unit of code is working as expected.

Let's take a look at an example. Let's say we have a function that adds two numbers together:

function add(a, b) {
  return a + b;
}

We can test this function by calling it with different values and making sure that the result is what we expect. For example, we can test that add(1, 2) returns 3:

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});

The test function is provided by Jest. It takes two arguments: the name of the test and a function that contains the test. The function that contains the test is called a test case. In this case, we are testing that add(1, 2) returns 3.

Setup

Let's first install jest in our react application.

pnpm install --save-dev jest babel-jest @babel/preset-env @babel/preset-react @babel/preset-typescript
pnpm install --save-dev @testing-library/react @types/jest jest-environment-jsdom
pnpm install --save-dev react-test-renderer @types/react-test-renderer

Then, let's create a file called jest.config.cjs in the root of our project with the following content:

module.exports = {
  testEnvironment: 'jest-environment-jsdom',
  setupFiles: ['./jest.setup.js'],
};

Then, let's create a file called jest.setup.cjs in the root of our project. You can leave empty for now.

Finally, let's create a file called babel.config.cjs in the root of our project with the following content:

module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { esmodules: true } }],
    ['@babel/preset-react', { runtime: 'automatic' }],
    '@babel/preset-typescript',
  ],
  plugins: [
    // This plugin is needed to make Jest work with vite meta import statements
    function () {
      return {
        visitor: {
          MetaProperty(path) {
            path.replaceWithSourceString('process');
          },
        },
      };
    },
  ],
};

Now we can add the test script in our package.json file:

{
  "scripts": {
    "test": "jest --watchAll"
  }
}

Now let's start testing.

Exercise

Let's create a tests for:

  • The button atom (create one if you don't have one)
    • Test that the button is rendered with snapshot testing
    • Test that the button is rendered with the correct text with snapshot testing
    • Test that the button is rendered with the correct color for each variant with snapshot testing
  • Test actions of a reducer (without rtk query)
  • Test a component that uses rtk query reducer