Testing React apps with Testing library

·

6 min read

Testing is an essential aspect of software development that ensures the quality and reliability of software products. React, being one of the most popular JavaScript frameworks, requires a robust testing strategy to ensure that the application functions as expected. Throughout this March and April, I had a chance to learn a lot about writing tests in React while building ClickPesa’s UI component library. In this article, I will share some of the things that I have learned.

Essential things you can test for in React components

  1. Render: Ensure that the component renders without throwing any errors.

  2. Props: Test that the component accepts and uses props correctly.

  3. State: Test that the component updates its state correctly.

  4. Events: Test that the component handles events correctly.

  5. Lifecycle methods: Test that the component correctly handles its lifecycle methods such as componentDidMount, componentDidUpdate, and componentWillUnmount.

  6. Snapshot testing: Use snapshot testing to ensure that the component's UI doesn't unexpectedly change over time.

  7. Accessibility: Test that the component is accessible to users with disabilities.

  8. Integration testing: Test that the component works correctly when integrated with other components.

  9. Performance: Test that the component doesn't have any performance issues or memory leaks.

  10. Error handling: Test that the component handles errors and edge cases gracefully.

  11. API calls: Test that the component makes API calls correctly and handles the response appropriately.

  12. Security: Test that the component doesn't introduce any security vulnerabilities.

  13. Routing: Test that the component navigates correctly between routes in the application.

  14. Authentication: Test that the component handles authentication and authorization correctly.

  15. Edge cases: Test that the component handles edge cases, such as empty or null props, correctly.

What is React's Testing Library?

React's Testing Library is a testing framework designed to test React components in a way that closely mimics how users interact with the application. The Testing Library provides a set of utilities that allow developers to write tests that simulate user interactions with the components and check that the application behaves correctly.

The Testing Library is built on top of the Jest testing framework, which is a popular testing tool in the React community. Jest provides a test runner and an assertion library, while the Testing Library provides a set of utilities to help developers write tests.

The key philosophy behind the Testing Library is to test components as if you were a user interacting with the application. This approach makes it easier to write tests that closely resemble the user experience and ensure that the application is working as intended.

How to use React's Testing Library?

To use React's Testing Library, you need to install it as a dependency in your project. If you created your project using create-react-app or bit dev, this library comes pre-installed. To install manually, you can do this by running the following command in your terminal:

npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event @types/jest

Once you have installed the Testing Library and other dependencies, you can start writing tests. Let's take a look at an example of how to test a simple React component using the Testing Library.

Suppose we have a simple component called "Counter" that displays a counter value and allows the user to increment and decrement it. Here's what the component looks like:

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleIncrement = () => {
    setCount(count + 1);
  }

  const handleDecrement = () => {
    setCount(count - 1);
  }

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={handleIncrement}>Increment</button>
      <button onClick={handleDecrement}>Decrement</button>
    </div>
  );
}

export default Counter;

To test this component using the Testing Library, we can write a test that checks that the counter value starts at 0, increments when the "Increment" button is clicked, and decrements when the "Decrement" button is clicked.

Here's what the test looks like:

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import Counter from './Counter';

test('counter increments and decrements correctly', () => {
  const { getByText } = render(<Counter />);

  // check that the counter starts at 0
  const counterValue = getByText('0');
  expect(counterValue).toBeInTheDocument();

  // click the increment button and check that the counter increments
  const incrementButton = getByText('Increment');
  fireEvent.click(incrementButton);
  expect(counterValue).toHaveTextContent('1');

  // click the decrement button and check that the counter decrements
  const decrementButton = getByText('Decrement');
  fireEvent.click(decrementButton);
  expect(counterValue).toHaveTextContent('0');
});

In this test, we first render the Counter component using the render function from the Testing Library. We then use the getByText function to find the "0" text node and check that it is in the document. We then simulate a click on the "Increment" button using the fireEvent.click function and check that the counter value is updated correctly using the toHaveTextContent assertion.

We then simulate a click on the "Decrement" button and check that the counter value is updated correctly using the same assertion.

This is a simple example, but it illustrates the power and simplicity of the Testing Library. With just a few lines of code, we can test that our component behaves correctly and that the user experience is what we expect.

Best practices for testing with React's Testing Library

To get the most out of React's Testing Library, there are some best practices that you should follow:

Test behavior, not implementation

When writing tests, focus on testing the behavior of your components, not their implementation details. This means that you should test what your component does, not how it does it. This approach makes your tests more resilient to changes in the implementation and ensures that they remain valid even if you refactor your code.

Test user interactions

Since the Testing Library is designed to test components as if you were a user interacting with the application, you should focus on testing user interactions. This means that you should simulate clicks, key presses, and other user actions to ensure that your components behave as expected.

Keep your tests small and focused

When writing tests, it's important to keep them small and focused. Each test should test a single piece of functionality or behavior. This approach makes it easier to debug failing tests and ensures that your tests remain maintainable over time.

Use descriptive test names

To make your tests more readable and understandable, use descriptive test names. Your test names should describe what the test does and what it's testing. This makes it easier to understand what your tests are doing and what they're testing.

Conclusion

React's Testing Library is a powerful tool that can help you create high-quality and maintainable code. By testing your components as if you were a user interacting with the application, you can ensure that your code behaves correctly and meets your users' expectations. In this article, we've explored how to use React's Testing Library and some best practices for writing tests. By following these best practices, you can write tests that are resilient, maintainable, and easy to understand.

Thank you for reading this article on testing React applications using React's Testing Library. We hope that you found it informative and helpful in your development process. If you're interested in learning more about software development, fintech, and other related topics, be sure to check out the ClickPesa publication. Our team is constantly writing and publishing articles that cover a range of topics related to software development, product design, and entrepreneurship.

At ClickPesa, we are passionate about building products that help people and businesses succeed in today's digital economy. If you're interested in learning more about our products and services, be sure to visit our website and follow us on social media.