---
title: "How To Write Integration Tests With Jest And React Testing Library | CoderPad"
description: "When you build applications or websites as a developer, your primary goal is to ensure it works. To ensure it works, you test your application by checking if it works as expected, but we often perform this testing manually, which is referred to as manual testing. Learn how to write integration tests in React using Jest"
canonical: "https://coderpad.io/blog/development/how-to-write-integration-tests-with-jest-and-react-testing-library/"
last_modified: "2026-04-15 16:21:01"
---
[Back to blog](https://coderpad.io/blog/)

# How To Write Integration Tests With Jest And React Testing Library

December 9, 2022 11 Minute Read

By Joel Olawanle

[Development](https://coderpad.io/blog/development/)

When you build applications or websites as a developer, your primary goal is to ensure it works. To ensure it works, you test your application by checking if it works as expected, but we often perform this testing manually, which is referred to as manual testing.

In this article, you will learn what testing means, the various types of testing, why you need to test, how testing works in React, what integration testing means, and how to write an integration test with the React testing library.

## What is testing?

Testing is the act or process of interacting with an application to ensure all its functionalities and features work as intended. There are generally two types of tests: manual and automated.

Manual testing involves an individual or group of people (mostly handled by the quality assurance team) who interact with your application to ensure every functionality works as intended. This type of testing gets cumbersome when working with large applications. For example, when a new feature is released, you would not only test that feature but will have to test the entire application and repeat this for every little change.

This becomes time-consuming, and you can be at the risk of human error when testing is done under pressure because no human is above mistakes. To avoid these drawbacks, we make use of automated testing.

Automated testing is the act of writing programs or code to automate the process of testing your application. This will also require writing extra testing code when you create a new feature, but you’ll not need to re-write the entire test for your application. And this will also be accurate based on your code, eliminating human error, and it becomes easy to identify and fix features that break tests. Overall it gives you confidence when shipping your application.

### Types of Automated Tests

To ensure your application is thoroughly tested, three different types of automated tests exist. These tests are as follows:

1. Unit tests

2. Integration tests

3. E2E (end-to-end) tests

Unit tests involve testing an individual block/unit of your application in isolation from other units. This unit can be a component, function, or class. Integration test involves testing a combination of units to ensure they work together. Finally, the E2E test involves testing your entire application flow to ensure everything works as designed from start to finish.

This guide will focus on integration tests. The question that will come to your mind is why?

## Why Write Integration Tests?

One importance of writing tests is that you become confident when shipping your application. Still, it’s also essential to write the right test and write only a few tests because, at a point, it would become difficult to maintain.

Unit tests are fast to write and run, but they involve testing independent units of your application, not how they work together. E2E test, on the other hand, is used to test your entire application ensuring proper communication with other systems, interfaces, and databases. Still, writing and running the E2E test takes a lot of time and can be expensive in terms of efficiency, time, and money.

This leaves us with the last option, which is the integration test. The integration test strikes a balance between the unit and E2E tests. This is one of the best, most moderate, cheap, and most efficient tests you can write for your application. It lets you test how your application’s components work together.

>

![ℹ️](https://coderpad.io/assets/emoji/2139.svg) This doesn’t mean that both unit and E2E tests are useless or you shouldn’t write them. It just means that writing more integration tests is better and more intelligent because it provides you with confidence.

## How testing works in React

Two major libraries, make it possible to write tests and test your React application. These libraries are [Jest](https://jestjs.io/) and the [React testing library (RTL)](https://testing-library.com/docs/react-testing-library/intro/). The React testing library was created by [Kent C. Dodds](https://kentcdodds.com/) and built on the [DOM Testing Library](https://testing-library.com/docs/dom-testing-library/intro/) by adding APIs for working with React components. At the same time, Jest is a JavaScript testing framework, but in React, it serves as a test runner that finds the test, runs the test, determines if a test pass or fails, and returns it in a human-readable format.

When you create a React application with [create-react-app](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app), by default, these dependencies are installed and ready to be used. Although you may overlook the Jest dependency in your package.json file because it is a dependency to react-script dependency, so when you inspect the react-script directory in your`node_modules`folder, you will notice it.

### How to run tests in React

When you scaffold your React application with [create-react-app](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app), you will notice a sample test file (`App.test.tsx`) created for the`App.tsx`file in your project’s`src`directory.

You may not understand what the code in the`App.test.tsx`file is all about but let’s first learn how to run the test. You can run tests in React with the test command in your terminal. By default, the command has been created as part of your default script when you check package.json

```
"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
},Code language: JSON / JSON with Comments (json)
```

You can run the following command in your terminal, which will run the test file.

```
$ npm run test
```

When you run the command, some options will appear, “type ‘a’ to run all tests”, and then you will get the following output which shows that you have one test with the name “renders learn react link”, and the test is successful.

```
PASS src/App.test.tsx
✓ renders learn react link (10 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.167 s, estimated 1 s
Ran all test suites.
```

Suppose there is an error; it will show that the test failed and explain what caused the failure—making it possible for you to fix it quickly.

### Structure of tests

When you open the`App.test.tsx`file, you will notice some codes for testing the`App.tsx`component, which may not make sense to you yet but will soon make sense. It is important to understand that when naming a test file, you should always add`.test`after the component name and before the file extension. This makes it possible for Jest to notice it as a test file and run it when you run the test command.

When creating a test, you will make use of the test method, which accepts two major parameters: the name of the test (test identifier) and a callback function that will hold the various test instructions:

```
test('test identifier', () => {
    // test instructions
});Code language: JavaScript (javascript)
```

## Building demo project

For this article, you’ll build a todo application comprising three components:`App`,`Todos`, and`AddTodo`, allowing you to add, delete and toggle todos in the [CoderPad React sandbox](https://app.coderpad.io/sandbox).

Image showing the various components of the todo project

The`App.tsx`file is the parent component that will be tested. It houses the`AddTodo.tsx`and`Todos.tsx`components:

```
import { useState } from 'react';
import AddTodo from './components/AddTodo';
import Todos from './components/Todos';

const App = () => {
    const [todos, setTodos] = useState([{ id: 2, text: 'Visit the mall to get laptop charger', completed: false },
    {
        id: 1,
        text: 'Get a new shoe at the store for tomorrows event',
        completed: true,
    },
    ]);

    const addTodo = (newTodo) => {
    setTodos([newTodo, ...todos]);
    };

    const toggleTodo = (id) => {
    setTodos(
        todos.map((todo) => {
        if (todo.id === id) {
            return {
            ...todo,
            completed: !todo.completed,
            };
        }
        return todo;
        })
    );
    };

    const deleteTodo = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id));
    };

    return (
    <div className="container">
        <h1 className="center">Todo's</h1>
        <AddTodo todos={todos} addTodo={addTodo} />
        <Todos todos={todos} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />
    </div>
    );
};

export default App;Code language: JavaScript (javascript)
```

In the code above, I added all the functionalities responsible for adding, removing, and toggling todos in this component. Also, the`todos`state stores all the todos with two default todos added.

The`AddTodo.tsx`component contains the form alone, and the`addTodo`method is passed in as a`prop`from the`App`component:

```
import { useState } from "react"

const AddTodo = ({ todos, addTodo }) => {
    const [todo, setTodo] = useState('')
    let newTodo = {
        id: todos.length + 1,
        text: todo,
        completed: false
    }

    const handleSubmit = (e) => {
        e.preventDefault()
        addTodo(newTodo)
        setTodo('')
    }

    return (
        <div className="add-todo__container">
            <input type="text" className="add-todo__input" value={todo} onChange={(e) => setTodo(e.target.value)} />
            <button className="add-todo__button" onClick={handleSubmit}>Add Todo</button>
        </div>
    )
}

export default AddTodo;Code language: JavaScript (javascript)
```

The second component is the`Todos.tsx`component which receives the array of all`todos`as a prop alongside methods to delete and toggle a todo:

```
import Todo from "./Todo"

const Todos = ({ todos, toggleTodo, deleteTodo }) => {
    return (
        <div className="all-todos__container">
            <h2>{todos.length} {todos.length > 1 ? 'Todos' : 'Todo'}</h2>
            {todos.map((todo) => <Todo key={todo.id} todo={todo} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />)}
        </div>
    )
}

export default Todos;Code language: JavaScript (javascript)
```

Finally, the`todo`item is separated into a new component`Todo.tsx`. This component receives each todo item as a prop and also the`deleteTodo`and`toggleTodo`methods:

```
import { MdRadioButtonChecked } from 'react-icons/md';
import { MdRadioButtonUnchecked } from 'react-icons/md';
import { AiOutlineDelete } from 'react-icons/ai';

const Todo = ({ todo, toggleTodo, deleteTodo }) => {
    return (
        <div className="todo__container ">
            <div className="todo__checkbox" onClick={() => toggleTodo(todo.id)}>
                {todo.completed ? <MdRadioButtonChecked className='icon checked' /> : <MdRadioButtonUnchecked className='icon' />}
            </div>
            <div className={todo.completed ? 'todo__text complete' : 'todo__text'}>
                <p>{todo.text}</p>
            </div>
            <div className="todo__delete" onClick={() => deleteTodo(todo.id)}>
                <AiOutlineDelete className='icon' />
            </div>
        </div>
    )
}

export default Todo;Code language: JavaScript (javascript)
```

With the todo application in place, let’s proceed to write integration tests for the component.

## Writing Integration Test

To understand how integration testing works, you’ll be introduced to the methods contained in the`@testing-library/react`library and how to use them by first writing a sample test before testing the Todo component.

### Example test

For the example test, you’ll test the heading text if it truly exists in the component. You’ll use the render method and screen object from`@testing-library/react`library to render the component and execute the`getByText`method.

>

💡 The [render](https://testing-library.com/docs/react-testing-library/api/#render) method is used to specify the component to be tested, while the [screen](https://testing-library.com/docs/queries/about#screen) object holds [several query methods](https://testing-library.com/docs/queries/about/) that can be used to access elements within the DOM. An example of this query is the [`getByText`method](https://testing-library.com/docs/queries/bytext).

```
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';Code language: JavaScript (javascript)
```

>

![ℹ️](https://coderpad.io/assets/emoji/2139.svg) I imported`@testing-library/jest-dom`, which is a companion library for React Testing Library and would help run your test methods. Some methods like [`toBeInTheDocument()`is not part of React Testing Library](https://stackoverflow.com/questions/56547215/react-testing-library-why-is-tobeinthedocument-not-a-function), so you will need to install [jest-dom](https://github.com/testing-library/jest-dom/) to enable it.

This article demonstrates [how to use Jest with React](https://coderpad.io/resources/docs/interview/more-coderpad-resources/supported-technologies-languages/unit-testing/using-jest-with-react/).

In`App.test.tsx`, add the following:

```
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import App from './App';

test('if the heading is correct', () => {
    render(<App />);
    const headingElement = screen.getByText(/Todo's/i);
});Code language: JavaScript (javascript)
```

In the code block above, the “ if the heading is correct ” test block uses the`render`and`screen`methods. The render method renders the`App`component and the screen method retrieves the element with the text “ Todo’s ”. The element is stored in the`headingElement`variable.

>

💡 When naming your tests, use descriptive names. Also, when passing text identifiers into methods like the`getByText()`method, you can use string or regex as seen below, but regex is preferred as it makes it easy to ignore casing using the`i`flag.

```
screen.getByText('Todo's');
screen.getByText(/Todo's/i);Code language: JavaScript (javascript)
```

At this point, the heading element has been stored in the`headingElement`variable. You can now use the`expect()` [assertion method](https://blog.bitsrc.io/the-most-important-assertions-in-jest-react-testing-library-tests-276fd745db38) to test if any element with the text “ Todo’s ” exist:

This test renders the component to be tested, gets the element with the “ Todo’s ” text, and checks if it exists in the document. When you run the test with `npm run test`, you will notice it passes:

```
PASS src/App.test.tsx
✓ if the heading is correct (13 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.325 s, estimated 1 s
Ran all test suites.
```

Now that you understand how the render and screen method work, let’s write the test for adding single and multiple todos and deleting a todo.

### Test adding and displaying a single todo

This will test across all the components and check if adding a new todo item will work or throw an error. To do this, you will create a new test, give it your preferred name, and then render the component to be tested (which is`App.tsx`):

```
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import App from './App';

test('typing into input and displaying todo', () => {
    render(<App />);
});Code language: JavaScript (javascript)
```

Then you can proceed to retrieve the input element and the button element using the screen method. You can retrieve these elements with any property or attribute of your choice, such as the placeholder text for the input and lots more.

```
const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
const buttonElement = screen.getByRole('button', { name: /Add Todo/i });Code language: JavaScript (javascript)
```

The code above retrieve the input element with the placeholder value, which will check your code for any placeholder with the value “ Add a new todo … ” and store the input element in the`inputElement`variable. Secondly, it will get the button using the`getByRole`query, which searches for any button with the value “ Add Todo “.

You can now test adding a value to the input element and click the “ Add Todo ” button. You will do this with the`fireEvent`method. This method allows you to fire events to simulate user actions such as click events, change events, and lots more.

```
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import App from './App';

test('typing into input and displaying todo', () => {
    render(<App />);
    const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
    const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
    fireEvent.change(inputElement, { target: { value: 'Send a mail to Dad' } });
    fireEvent.click(buttonElement);
});Code language: JavaScript (javascript)
```

>

![ℹ️](https://coderpad.io/assets/emoji/2139.svg) You need to import the`fireEvent method`from`@testing-library/react`so you can use it within your test file.

In the code above, you are testing the add todo form by adding a new todo with the value “Send a mail to Dad” into the`inputElement`and then clicking the`buttonElement`.

The last step would be to validate the test by checking if this todo item is added to the Todo component. You can use the`screen`method and the`expect`assertion to check if it exists in the DOM/document.

```
const todoElement = screen.getByText(/Send a mail to Dad/i);
expect(todoElement).toBeInTheDocument(); Code language: JavaScript (javascript)
```

Overall, the entire test for typing into input and displaying todo will look like this:

```
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import App from './App';

test('typing into input and displaying todo', () => {
    render(<App />);
    const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
    const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
    fireEvent.change(inputElement, { target: { value: 'Send a mail to Dad' } });
    fireEvent.click(buttonElement);
    const todoElement = screen.getByText(/Send a mail to Dad/i);
    expect(todoElement).toBeInTheDocument();
});Code language: JavaScript (javascript)
```

When you run the test, it will display the outcomes indicating that all tests passed:

```
PASS src/App.test.tsx
✓ typing into input and displaying todo (39 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.477 s, estimated 1 s
Ran all test suites.
```

### Test adding and displaying multiple todos

So far, you have learned how to test the addition of only one todo, but in the actual sense, you’ll want to have more than one todo in your application, so let’s test by adding multiple todos into the application.

You might think of repeating some lines of code, but what if you want to add 100 todos? Then it’s not realistic:

```
test('typing into input and displaying muliple todos', () => {
    render(<App />);
    const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
    const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
    fireEvent.change(inputElement, { target: { value: 'Send a mail to Dad' } });
    fireEvent.click(buttonElement);
    fireEvent.change(inputElement, { target: { value: 'Get some gifts for Bae' },});
    fireEvent.click(buttonElement);
    const todoElement1 = screen.getByText(/Send a mail to Dad/i);
    expect(todoElement1).toBeInTheDocument();
    const todoElement2 = screen.getByText(/Get some gifts for Bae/i);
    expect(todoElement2).toBeInTheDocument();
});Code language: JavaScript (javascript)
```

Instead of having to repeat these lines, you can create a function to handle the addition of multiple todos so you can use a loop:

```
const addTodo = (todos) => {
    const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
    const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
    todos.forEach((todo) => {
        fireEvent.change(inputElement, { target: { value: todo } });
        fireEvent.click(buttonElement);
    });
};Code language: JavaScript (javascript)
```

This function will receive an array of`todos`, then loops through these todos to add them to your application. You can call this function and pass in all the todos within your test:

```
test('typing into input and displaying all todos', () => {
    render(<App />);
    addTodo(['Send a mail to Dad', 'Get some gifts for Bae']);
    const todoElements = screen.queryAllByTestId('todo');
    expect(todoElements.length).toBe(4);
});Code language: JavaScript (javascript)
```

Finally, you’ll need to validate your test. In the previous test, you checked if the todo added was in the document by using`expect(todoElement).toBeInTheDocument()`, but since you now have more than one todo, doing so for each can be time-consuming. Instead, you can check for the number of todos in your DOM if the number matches what you are expecting.

For example, looking through the application, you’ll notice that two`todo`items were added to the`todo`state at the beginning. This means that because you are adding two new items, you expect four todos to appear on the DOM, which is why the number four is used in the following assertion:

```
expect(todoElements.length).toBe(4);Code language: JavaScript (javascript)
```

When you run the test, you will notice it passes:

```
PASS src/App.test.tsx
App
✓ typing into input and displaying all todos (41 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.595 s, estimated 1 s
Ran all test suites.
```

But suppose you estimated the total number of elements to be two, then it will throw an error and explain the cause of the error:

```
FAIL src/App.test.tsx
    App
    ✕ typing into input and displaying all todos (42 ms)

    ● App > typing into input and displaying all todos

    expect(received).toBe(expected) // Object.is equality

    Expected: 2
    Received: 4

        33 | addTodo(['Send a mail to Dad', 'Get some gifts for Bae']);
        34 | const todoElements = screen.queryAllByTestId('todo');
    > 35 | expect(todoElements.length).toBe(2);
            | ^
        36 | });
        37 | });
        38 |

        at Object.<anonymous> (src/App.test.tsx:35:31)
        at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
        at runJest (node_modules/@jest/core/build/runJest.js:404:19)

Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.482 s, estimated 1 s
Ran all test suites.Code language: JavaScript (javascript)
```

### Performing multiple tests

Suppose you want a dedicated test for each function/feature of your application in one test file. You can use the`describe`method, which works like the`test`method but can hold more than one`test`:

```
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import App from './App';

const addTodo = (todos) => {
    const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
    const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
    todos.forEach((todo) => {
        fireEvent.change(inputElement, { target: { value: todo } });
        fireEvent.click(buttonElement);
    });
};

describe('App', () => {
    test('typing into input and displaying one todo', () => {
        render(<App />);
        const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
        const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
        fireEvent.change(inputElement, { target: { value: 'Send a mail to Dad' } });
        fireEvent.click(buttonElement);
        const todoElement = screen.getByText(/Send a mail to Dad/i);
        expect(todoElement).toBeInTheDocument();
    });

    test('typing into input and displaying all todos', () => {
        render(<App />);
        addTodo(['Send a mail to Dad', 'Get some gifts for Bae']);
        const todoElements = screen.queryAllByTestId('todo');
        expect(todoElements.length).toBe(4);
    });
});Code language: JavaScript (javascript)
```

>

![ℹ️](https://coderpad.io/assets/emoji/2139.svg) The`describe`method or block is a test suite used to hold more than one test (test case). This`describe`block has two parameters like the`test`block: the name or identifier (a string) and a callback function to hold all your`test`blocks or cases.

In the above, you have two tests, one will check if you can add one todo item to your application, and the second will check if you can add multiple todos. When you run the code, it will indicate that two tests passed and also list the names of the tests (identifiers):

```
PASS src/App.test.tsx
App
✓ typing into input and displaying one todo (34 ms)
✓ typing into input and displaying all todos (11 ms)

Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 0.314 s, estimated 1 s
Ran all test suites.
```

### Test deleting a todo

Finally, let’s also test how you can select a single todo and delete it from your application just like you’d do if it were manual testing. You can also use a function to get the todo, the container, and the delete button to fire a click event.

```
const deleteTodo = (todo) => {
    const todoElement = screen.getByText(todo);
    const todoElementContainer = todoElement.closest('div');
    const deleteButton = within(todoElementContainer).getByTestId('delete');
    fireEvent.click(deleteButton);
};Code language: JavaScript (javascript)
```

The function receives a todo; you then write test instructions to look for the todo element and get the entire todo container to be removed using the`closest`method. Then get the`deleteButton`from within the`todoElementContainer`and fire a click event that removes the todo. You can call this function in the test:

```
test('if delete button is working', () => {
    render(<App />);
    addTodo(['Send a mail to Dad', 'Get some gifts for Bae']);
    deleteTodo('Send a mail to Dad');
    const todoElements = screen.queryAllByTestId('todo');
    expect(todoElements.length).toBe(3);
});Code language: JavaScript (javascript)
```

In the test, you can add new todos with the`addTodo()`function, then call the`deleteTodo()`function by passing the`todo`to be deleted. To assert this test (if one has deleted), you can check your application’s total number of`todos`. This is done by checking the length — meaning it must have reduced from four to three.

This is what the entire test, alongside other tests, looks like:

```
import { render, screen, fireEvent, within } from '@testing-library/react';
import '@testing-library/jest-dom';
import App from './App';

const addTodo = (todos) => {
    const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
    const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
    todos.forEach((todo) => {
        fireEvent.change(inputElement, { target: { value: todo } });
        fireEvent.click(buttonElement);
    });
};

const deleteTodo = (todo) => {
    const todoElement = screen.getByText(todo);
    const todoElementContainer = todoElement.closest('div');
    const deleteButton = within(todoElementContainer).getByTestId('delete');
    fireEvent.click(deleteButton);
};

describe('App', () => {
    test('typing into input and displaying one todo', () => {
        render(<App />);
        const inputElement = screen.getByPlaceholderText(/Add a new todo .../i);
        const buttonElement = screen.getByRole('button', { name: /Add Todo/i });
        fireEvent.change(inputElement, {
            target: { value: 'Send a mail to Dad'},
        });
        fireEvent.click(buttonElement);
        const todoElement = screen.getByText(/Send a mail to Dad/i);
        expect(todoElement).toBeInTheDocument();
    });

    test('typing into input and displaying all todos', () => {
        render(<App />);
        addTodo(['Send a mail to Dad', 'Get some gifts for Bae']);
        const todoElements = screen.queryAllByTestId('todo');
        expect(todoElements.length).toBe(4);
    });

    test('if delete button is working', () => {
        render(<App />);
        addTodo(['Send a mail to Dad', 'Get some gifts for Bae']);
        deleteTodo('Send a mail to Dad');
        const todoElements = screen.queryAllByTestId('todo');
        expect(todoElements.length).toBe(3);
    });
});Code language: JavaScript (javascript)
```

When you run the test, you will notice that three tests have passed:

```
PASS src/App.test.tsx
App
✓ typing into input and displaying one todo (43 ms)
✓ typing into input and displaying all todos (21 ms)
✓ if delete button is working (18 ms)

Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 0.737 s, estimated 1 s
Ran all test suites.Code language: JavaScript (javascript)
```

Run the test in the sandbox below:

## Wrapping up

In this article, you have learned what the integration test means, how it is differentiated from other tests, and why it stands out. You have also learned how to write integration tests in React. You can check out the final project, which includes the working test file [in this repository](https://github.com/olawanlejoel/integration-test-todo-app/tree/todo-app-with-test).

Have fun coding!

I’m Joel Olawanle, a frontend developer and technical writer interested in making the web accessible to everyone by always looking for ways to give back to the tech community. Follow me and connect with me on [Twitter](https://twitter.com/olawanle_joel).

## Subscribe for more CoderPad insights

## Trending Articles

Previous slide Next slide [Development

## What is Prompt Engineering?

Introducing AI tools such as ChatGPT and Bard helps increase the efficiency of tasks such as data generation, code generation and completion, text summarization, etc. How were these AI tools trained to answer almost every question you ask them? The answer, prompt engineering, is discussed in this blog post.

Read the post](https://coderpad.io/blog/development/what-is-prompt-engineering/) [Development

## A Guide To Using React’s useCallback() Hook

Are you looking to optimize your React applications? Have you heard of the useCallback hook? useCallback is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. In this post, we'll dive into React's useCallback() hook, define referential equality and callback functions and how to tie it all together.

Read the post](https://coderpad.io/blog/development/a-guide-to-using-reacts-usecallback-hook/) [Development

## MySQL vs. PostgreSQL: How Do They Compare?

A database is a convenient tool that allows users to access information, maintain records, and apply commonly used operations, such as insertion, modification, deletion, and data organization. Learn about MySQL vs PostgreSQL, their features, advantages, and disadvantages. Finally, check out which one is the best choice for you.

Read the post](https://coderpad.io/blog/development/mysql-vs-postgresql-how-do-they-compare/) [Development

## PostgreSQL LIKE Operator: A Detailed Guide

When using databases, searching for values that match a given pattern is a familiar necessity. Learn how you can retrieve entries with queries including a particular string using Postgres LIKE operator.

Read the post](https://coderpad.io/blog/development/postgresql-like-operator-a-detailed-guide/) [Development

## How To Use DataProvider In TestNG With Examples

When it comes to testing there are many tools and techniques available. In this post, we'll discuss how to use DataProvider with TestNG.

Read the post](https://coderpad.io/blog/development/how-to-use-dataprovider-in-testng-with-examples/) [Development

## How To Get Up And Running With Django Migrations: A Guide

Django migrations are a way of handling the application of changes to a database schema. By following the steps outlined in this guide, you can easily set up and use migrations in your Django projects.

Read the post](https://coderpad.io/blog/development/how-to-get-up-and-running-with-django-migrations-a-guide/) [Development

## Writing A Parameterized Test In JUnit With Examples

A JUnit parameterized test allows you to decouple data from structure, generating cleaner and more reliable tests. Learn more in this guide.

Read the post](https://coderpad.io/blog/development/writing-a-parameterized-test-in-junit-with-examples/) [Development

## How To Use Assert In JUnit With Examples

The JUnit Assert class is what you use to write unit testing assertions in JUnit. Learn more about it in this guide, full of examples.

Read the post](https://coderpad.io/blog/development/how-to-use-assert-in-junit-with-examples/) [Development

## A Simple Guide To TypeORM: What It Is And How To Use It

Considering current languages have object-oriented programming features, most database management systems are based on the relational model, with tables instead of objects. For these reasons, mapping relational objects is very important in development. In this article, you will learn what TypeORM, one of the main tools used today, is.

Read the post](https://coderpad.io/blog/development/a-simple-guide-to-typeorm-what-it-is-and-how-to-use-it/) [Development

## Using PreparedStatement in JDBC With Examples

In this post, we'll see why and how to work with JDBC and PreparedStatement. We will also learn along with examples using code.

Read the post](https://coderpad.io/blog/development/using-preparedstatement-in-jdbc-with-examples/) [Development

## React vs React Native: The Differences Explained

React and React Native are similar in that they both allow web developers to build applications based on the unique concept of components. But the two frameworks do this in radically different ways. In this post, we cover the key differences between react and react native frameworks, implementation, and which is an appropriate choice.

Read the post](https://coderpad.io/blog/development/react-vs-react-native-the-differences-explained/) [Development

## Logging in Django

The most challenging part of fixing a problem is identifying it. Unfortunately, this statement is exceptionally true when it comes to debugging. Learn how to use the power of logging into your Django applications to improve your debug process in this article.

Read the post](https://coderpad.io/blog/development/logging-in-django/)

## Hire with confidence.

See why engineering teams trust CoderPad to evaluate developers with realistic, AI-ready hiring workflows.

[Request a demo](https://coderpad.io/sales/)
