Use Jest andreact-testing-library
The easiest way to start testing React components is to perform snapshot testing, which is a testing technique that allows you to isolate test components.
If you are familiar with testing software, it is like unit testing your classes: you test the functionality of each component.
I assume you created a React applicationcreate-react-app
, Already attachedjokeAfter installation, we will need the test package.
Let's start with a simple test. CodeSandbox is a good environment for experimentation. Start with the React sandbox, then create aApp.js
A componentcomponents
Folder and add aApp.test.js
file.
import React from 'react'
export default function App() {
return (
<div className=“App”>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
)
}
Our first test is stupid:
test('First test', () => {
expect(true).toBeTruthy()
})
When CodeSandbox detects the test files, it will automatically run them for you, and you can click the "Test" button at the bottom of the view to display the test results:
A test file can contain multiple tests:
Now let's do some more useful operations to actually test React components. Now we only have the App, which doesn't do anything really useful, so let's first set up the environment with a small app with more features: the counter app we built before. If you skip it, you can go back and read how we built it, but for ease of reference, I add it here again.
It has only 2 components: App and Button. createApp.js
file:
import React, { useState } from 'react'
import Button from './Button'
const App = () => {
const [count, setCount] = useState(0)
const incrementCount = increment => {
setCount(count + increment)
}
return (
<div>
<Button increment={1} onClickFunction={incrementCount} />
<Button increment={10} onClickFunction={incrementCount} />
<Button increment={100} onClickFunction={incrementCount} />
<Button increment={1000} onClickFunction={incrementCount} />
<span>{count}</span>
</div>
)
}
export default App
withButton.js
file:
import React from 'react'
const Button = ({ increment, onClickFunction }) => {
const handleClick = () => {
onClickFunction(increment)
}
return <button onClick={handleClick}>+{increment}</button>
}
export default Button
We will usereact-testing-library
, This is a great help because it allows us to check the output of each component and apply events to them. You can read more about it belowhttps://github.com/kentcdodds/react-testing-libraryOr watchThis video.
Let's test the Button component first.
We start with importrender
withfireEvent
Fromreact-testing-library
, Two helpers. The first one lets us render JSX. The second one lets us emit events on the component.
CreateButton.test.js
And put it in the same folder as thatButton.js
.
import React from 'react'
import { render, fireEvent } from 'react-testing-library'
import Button from './Button'
Buttons are used in the application to receive click events, and then they are called and passed toonClickFunction
pillar. We add acount
Variable, and then we create a function that increments it:
let count
const incrementCount = increment => {
count += increment
}
Now start the actual test. We first initialize count to 0, and then render one+1
Button
Component passed1
Toincrement
And ourincrementCount
Play a roleonClickFunction
.
Then we get the content of the first child of the component and check its output+1
.
Then, we continue to click the button and check if the count changes from 0 to 1:
test('+1 Button works', () => {
count = 0
const { container } = render(
<Button increment={1} onClickFunction={incrementCount} />
)
const button = container.firstChild
expect(button.textContent).toBe('+1')
expect(count).toBe(0)
fireEvent.click(button)
expect(count).toBe(1)
})
Similarly, we test a +100 button, this time check whether the output is+100
and the button click increments the count of 100.
test('+100 Button works', () => {
count = 0
const { container } = render(
<Button increment={100} onClickFunction={incrementCount} />
)
const button = container.firstChild
expect(button.textContent).toBe('+100')
expect(count).toBe(0)
fireEvent.click(button)
expect(count).toBe(100)
})
Now let's test the App component. It displays 4 buttons and results on the page. We can check each button and click on them multiple times to see if the result increases:
import React from 'react'
import { render, fireEvent } from 'react-testing-library'
import App from './App'
test(‘App works’, () => {
const { container } = render(<App />)
console.log(container)
const buttons = container.querySelectorAll(‘button’)
expect(buttons[0].textContent).toBe(’+1’)
expect(buttons[1].textContent).toBe(’+10’)
expect(buttons[2].textContent).toBe(’+100’)
expect(buttons[3].textContent).toBe(’+1000’)
const result = container.querySelector(‘span’)
expect(result.textContent).toBe(‘0’)
fireEvent.click(buttons[0])
expect(result.textContent).toBe(‘1’)
fireEvent.click(buttons[1])
expect(result.textContent).toBe(‘11’)
fireEvent.click(buttons[2])
expect(result.textContent).toBe(‘111’)
fireEvent.click(buttons[3])
expect(result.textContent).toBe(‘1111’)
fireEvent.click(buttons[2])
expect(result.textContent).toBe(‘1211’)
fireEvent.click(buttons[1])
expect(result.textContent).toBe(‘1221’)
fireEvent.click(buttons[0])
expect(result.textContent).toBe(‘1222’)
})
Check the code running on this CodeSandbox:https://codesandbox.io/s/pprl4y0wq
Download mine for freeResponse Handbook
More response tutorials:
- A simple React application example: Get GitHub user information through API
- Build a simple counter with React
- VS Code setup for React development
- How to pass props to child components through React Router
- Create an application using Electron and React
- Tutorial: Create a spreadsheet with React
- Roadmap for learning React
- Learn how to use Redux
- Getting started with JSX
- Stylized components
- Introduction to Redux Saga
- Introduction to React Router
- Introduction to React
- Reaction component
- Virtual DOM
- Reaction event
- Reaction state
- Reaction props
- Reaction fragment
- React Context API
- Reaction PropTypes
- Reaction Concept: Declarative
- React: How to display other components when clicked
- How to loop inside React JSX
- Props and status in React
- Should you use jQuery or React?
- How much JavaScript do I need to know to use React?
- Gatsby Introduction
- How to reference DOM elements in React
- One-way data flow in React
- React high-end components
- React to life cycle events
- Reaction concept: immutability
- Reaction concept: purity
- Introduction to React hooks
- Introduction to create-react-app
- Reaction concept: composition
- React: demo component and container component
- Code splitting in React
- Server-side rendering with React
- How to install React
- CSS in React
- Use SASS in React
- Processing forms in React
- Reaction strict mode
- Reaction portal
- React rendering props
- Test React components
- How to pass parameters to event handlers in React
- How to deal with errors in React
- How to return multiple elements in JSX
- Conditional rendering in React
- Reaction, how to transfer props to subcomponents
- How to get the value of an input element in React
- How to use useState React hook
- How to use useCallback React hook
- How to use useEffect React hook
- How to use useMemo React hook
- How to use useRef React hook
- How to use useContext React hook
- How to use useReducer React hook
- How to connect your React app to the backend of the same source
- Reaching the router tutorial
- How to use React Developer Tools
- How to learn React
- How to debug a React application
- How to render HTML in React
- How to fix `dangerouslySetInnerHTML` does not match the error in React
- How can I solve the problem of React login form status and browser auto-fill
- How to configure HTTPS in React application on localhost
- How to fix the "Component cannot be updated while rendering other components" error in React
- Can I use React hooks within the conditions?
- Using useState with objects: how to update
- How to move in code blocks using React and Tailwind
- React, focus on an item in React when added to the DOM
- Response, edit text on doubleclick