From d6f98dc2b244ce3095bed093a42b69997c41df09 Mon Sep 17 00:00:00 2001 From: xuel Date: Fri, 14 Oct 2022 14:44:51 +0800 Subject: [PATCH] init README_v1.md --- README.md | 681 +------------------------------------------------- README_v1.md | 689 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 697 insertions(+), 673 deletions(-) create mode 100644 README_v1.md diff --git a/README.md b/README.md index 45324901..92ac616c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ + + + +- [React Testing Library](#react-testing-library) + + +

React Testing Library

@@ -10,680 +17,8 @@ /> -

Simple and complete React DOM testing utilities that encourage good testing -practices.

- -
- -[**Read The Docs**](https://testing-library.com/react) | -[Edit the docs](https://github.com/testing-library/testing-library-docs) +

阅读、练习、翻译、整理、记录

-

- - -[![Build Status][build-badge]][build] -[![Code Coverage][coverage-badge]][coverage] -[![version][version-badge]][package] -[![downloads][downloads-badge]][npmtrends] -[![MIT License][license-badge]][license] -[![All Contributors][all-contributors-badge]](#contributors) -[![PRs Welcome][prs-badge]][prs] -[![Code of Conduct][coc-badge]][coc] -[![Discord][discord-badge]][discord] - -[![Watch on GitHub][github-watch-badge]][github-watch] -[![Star on GitHub][github-star-badge]][github-star] -[![Tweet][twitter-badge]][twitter] - - -
- - TestingJavaScript.com Learn the smart, efficient way to test any JavaScript application. - -
- -## Table of Contents - - - - -- [The problem](#the-problem) -- [The solution](#the-solution) -- [Installation](#installation) - - [Suppressing unnecessary warnings on React DOM 16.8](#suppressing-unnecessary-warnings-on-react-dom-168) -- [Examples](#examples) - - [Basic Example](#basic-example) - - [Complex Example](#complex-example) - - [More Examples](#more-examples) -- [Hooks](#hooks) -- [Guiding Principles](#guiding-principles) -- [Docs](#docs) -- [Issues](#issues) - - [🐛 Bugs](#-bugs) - - [💡 Feature Requests](#-feature-requests) - - [❓ Questions](#-questions) -- [Contributors](#contributors) -- [LICENSE](#license) - - - -## The problem - -You want to write maintainable tests for your React components. As a part of -this goal, you want your tests to avoid including implementation details of your -components and rather focus on making your tests give you the confidence for -which they are intended. As part of this, you want your testbase to be -maintainable in the long run so refactors of your components (changes to -implementation but not functionality) don't break your tests and slow you and -your team down. - -## The solution - -The `React Testing Library` is a very lightweight solution for testing React -components. It provides light utility functions on top of `react-dom` and -`react-dom/test-utils`, in a way that encourages better testing practices. Its -primary guiding principle is: - -> [The more your tests resemble the way your software is used, the more -> confidence they can give you.][guiding-principle] - -## Installation - -This module is distributed via [npm][npm] which is bundled with [node][node] and -should be installed as one of your project's `devDependencies`: - -``` -npm install --save-dev @testing-library/react -``` - -or - -for installation via [yarn][yarn] - -``` -yarn add --dev @testing-library/react -``` - -This library has `peerDependencies` listings for `react` and `react-dom`. - -_React Testing Library versions 13+ require React v18. If your project uses an -older version of React, be sure to install version 12:_ - -``` -npm install --save-dev @testing-library/react@12 - - -yarn add --dev @testing-library/react@12 -``` - -You may also be interested in installing `@testing-library/jest-dom` so you can -use [the custom jest matchers](https://github.com/testing-library/jest-dom). - -> [**Docs**](https://testing-library.com/react) - -### Suppressing unnecessary warnings on React DOM 16.8 - -There is a known compatibility issue with React DOM 16.8 where you will see the -following warning: - -``` -Warning: An update to ComponentName inside a test was not wrapped in act(...). -``` - -If you cannot upgrade to React DOM 16.9, you may suppress the warnings by adding -the following snippet to your test configuration -([learn more](https://github.com/testing-library/react-testing-library/issues/281)): - -```js -// this is just a little hack to silence a warning that we'll get until we -// upgrade to 16.9. See also: https://github.com/facebook/react/pull/14853 -const originalError = console.error -beforeAll(() => { - console.error = (...args) => { - if (/Warning.*not wrapped in act/.test(args[0])) { - return - } - originalError.call(console, ...args) - } -}) - -afterAll(() => { - console.error = originalError -}) -``` - -## Examples - -### Basic Example - -```jsx -// hidden-message.js -import * as React from 'react' - -// NOTE: React Testing Library works well with React Hooks and classes. -// Your tests will be the same regardless of how you write your components. -function HiddenMessage({children}) { - const [showMessage, setShowMessage] = React.useState(false) - return ( -
- - setShowMessage(e.target.checked)} - checked={showMessage} - /> - {showMessage ? children : null} -
- ) -} - -export default HiddenMessage -``` - -```jsx -// __tests__/hidden-message.js -// these imports are something you'd normally configure Jest to import for you -// automatically. Learn more in the setup docs: https://testing-library.com/docs/react-testing-library/setup#cleanup -import '@testing-library/jest-dom' -// NOTE: jest-dom adds handy assertions to Jest and is recommended, but not required - -import * as React from 'react' -import {render, fireEvent, screen} from '@testing-library/react' -import HiddenMessage from '../hidden-message' - -test('shows the children when the checkbox is checked', () => { - const testMessage = 'Test Message' - render({testMessage}) - - // query* functions will return the element or null if it cannot be found - // get* functions will return the element or throw an error if it cannot be found - expect(screen.queryByText(testMessage)).toBeNull() - - // the queries can accept a regex to make your selectors more resilient to content tweaks and changes. - fireEvent.click(screen.getByLabelText(/show/i)) - - // .toBeInTheDocument() is an assertion that comes from jest-dom - // otherwise you could use .toBeDefined() - expect(screen.getByText(testMessage)).toBeInTheDocument() -}) -``` - -### Complex Example - -```jsx -// login.js -import * as React from 'react' - -function Login() { - const [state, setState] = React.useReducer((s, a) => ({...s, ...a}), { - resolved: false, - loading: false, - error: null, - }) - - function handleSubmit(event) { - event.preventDefault() - const {usernameInput, passwordInput} = event.target.elements - - setState({loading: true, resolved: false, error: null}) - - window - .fetch('/api/login', { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({ - username: usernameInput.value, - password: passwordInput.value, - }), - }) - .then(r => r.json().then(data => (r.ok ? data : Promise.reject(data)))) - .then( - user => { - setState({loading: false, resolved: true, error: null}) - window.localStorage.setItem('token', user.token) - }, - error => { - setState({loading: false, resolved: false, error: error.message}) - }, - ) - } - - return ( -
-
-
- - -
-
- - -
- -
- {state.error ?
{state.error}
: null} - {state.resolved ? ( -
Congrats! You're signed in!
- ) : null} -
- ) -} - -export default Login -``` - -```jsx -// __tests__/login.js -// again, these first two imports are something you'd normally handle in -// your testing framework configuration rather than importing them in every file. -import '@testing-library/jest-dom' -import * as React from 'react' -// import API mocking utilities from Mock Service Worker. -import {rest} from 'msw' -import {setupServer} from 'msw/node' -// import testing utilities -import {render, fireEvent, screen} from '@testing-library/react' -import Login from '../login' - -const fakeUserResponse = {token: 'fake_user_token'} -const server = setupServer( - rest.post('/api/login', (req, res, ctx) => { - return res(ctx.json(fakeUserResponse)) - }), -) - -beforeAll(() => server.listen()) -afterEach(() => { - server.resetHandlers() - window.localStorage.removeItem('token') -}) -afterAll(() => server.close()) - -test('allows the user to login successfully', async () => { - render() - - // fill out the form - fireEvent.change(screen.getByLabelText(/username/i), { - target: {value: 'chuck'}, - }) - fireEvent.change(screen.getByLabelText(/password/i), { - target: {value: 'norris'}, - }) - - fireEvent.click(screen.getByText(/submit/i)) - - // just like a manual tester, we'll instruct our test to wait for the alert - // to show up before continuing with our assertions. - const alert = await screen.findByRole('alert') - - // .toHaveTextContent() comes from jest-dom's assertions - // otherwise you could use expect(alert.textContent).toMatch(/congrats/i) - // but jest-dom will give you better error messages which is why it's recommended - expect(alert).toHaveTextContent(/congrats/i) - expect(window.localStorage.getItem('token')).toEqual(fakeUserResponse.token) -}) - -test('handles server exceptions', async () => { - // mock the server error response for this test suite only. - server.use( - rest.post('/api/login', (req, res, ctx) => { - return res(ctx.status(500), ctx.json({message: 'Internal server error'})) - }), - ) - - render() - - // fill out the form - fireEvent.change(screen.getByLabelText(/username/i), { - target: {value: 'chuck'}, - }) - fireEvent.change(screen.getByLabelText(/password/i), { - target: {value: 'norris'}, - }) - - fireEvent.click(screen.getByText(/submit/i)) - - // wait for the error message - const alert = await screen.findByRole('alert') - - expect(alert).toHaveTextContent(/internal server error/i) - expect(window.localStorage.getItem('token')).toBeNull() -}) -``` - -> We recommend using [Mock Service Worker](https://github.com/mswjs/msw) library -> to declaratively mock API communication in your tests instead of stubbing -> `window.fetch`, or relying on third-party adapters. - -### More Examples - -> We're in the process of moving examples to the -> [docs site](https://testing-library.com/docs/example-codesandbox) - -You'll find runnable examples of testing with different libraries in -[the `react-testing-library-examples` codesandbox](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples). -Some included are: - -- [`react-redux`](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples/tree/main/?fontsize=14&module=%2Fsrc%2F__tests__%2Freact-redux.js&previewwindow=tests) -- [`react-router`](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples/tree/main/?fontsize=14&module=%2Fsrc%2F__tests__%2Freact-router.js&previewwindow=tests) -- [`react-context`](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples/tree/main/?fontsize=14&module=%2Fsrc%2F__tests__%2Freact-context.js&previewwindow=tests) - -You can also find React Testing Library examples at -[react-testing-examples.com](https://react-testing-examples.com/jest-rtl/). - -## Hooks - -If you are interested in testing a custom hook, check out [React Hooks Testing -Library][react-hooks-testing-library]. - -> NOTE: it is not recommended to test single-use custom hooks in isolation from -> the components where it's being used. It's better to test the component that's -> using the hook rather than the hook itself. The `React Hooks Testing Library` -> is intended to be used for reusable hooks/libraries. - -## Guiding Principles - -> [The more your tests resemble the way your software is used, the more -> confidence they can give you.][guiding-principle] - -We try to only expose methods and utilities that encourage you to write tests -that closely resemble how your React components are used. - -Utilities are included in this project based on the following guiding -principles: - -1. If it relates to rendering components, it deals with DOM nodes rather than - component instances, nor should it encourage dealing with component - instances. -2. It should be generally useful for testing individual React components or - full React applications. While this library is focused on `react-dom`, - utilities could be included even if they don't directly relate to - `react-dom`. -3. Utility implementations and APIs should be simple and flexible. - -Most importantly, we want React Testing Library to be pretty light-weight, -simple, and easy to understand. - -## Docs - -[**Read The Docs**](https://testing-library.com/react) | -[Edit the docs](https://github.com/testing-library/testing-library-docs) - -## Issues - -Looking to contribute? Look for the [Good First Issue][good-first-issue] label. - -### 🐛 Bugs - -Please file an issue for bugs, missing documentation, or unexpected behavior. - -[**See Bugs**][bugs] - -### 💡 Feature Requests - -Please file an issue to suggest new features. Vote on feature requests by adding -a 👍. This helps maintainers prioritize what to work on. - -[**See Feature Requests**][requests] - -### ❓ Questions - -For questions related to using the library, please visit a support community -instead of filing an issue on GitHub. - -- [Discord][discord] -- [Stack Overflow][stackoverflow] - -## Contributors - -Thanks goes to these people ([emoji key][emojis]): - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Kent C. Dodds
Kent C. Dodds

💻 📖 🚇 ⚠️
Ryan Castner
Ryan Castner

📖
Daniel Sandiego
Daniel Sandiego

💻
Paweł Mikołajczyk
Paweł Mikołajczyk

💻
Alejandro Ñáñez Ortiz
Alejandro Ñáñez Ortiz

📖
Matt Parrish
Matt Parrish

🐛 💻 📖 ⚠️
Justin Hall
Justin Hall

📦
Anto Aravinth
Anto Aravinth

💻 ⚠️ 📖
Jonah Moses
Jonah Moses

📖
Łukasz Gandecki
Łukasz Gandecki

💻 ⚠️ 📖
Ivan Babak
Ivan Babak

🐛 🤔
Jesse Day
Jesse Day

💻
Ernesto García
Ernesto García

💬 💻 📖
Josef Maxx Blake
Josef Maxx Blake

💻 📖 ⚠️
Michal Baranowski
Michal Baranowski

📝
Arthur Puthin
Arthur Puthin

📖
Thomas Chia
Thomas Chia

💻 📖
Thiago Galvani
Thiago Galvani

📖
Christian
Christian

⚠️
Alex Krolick
Alex Krolick

💬 📖 💡 🤔
Johann Hubert Sonntagbauer
Johann Hubert Sonntagbauer

💻 📖 ⚠️
Maddi Joyce
Maddi Joyce

💻
Ryan Vice
Ryan Vice

📖
Ian Wilson
Ian Wilson

📝
Daniel
Daniel

🐛 💻
Giorgio Polvara
Giorgio Polvara

🐛 🤔
John Gozde
John Gozde

💻
Sam Horton
Sam Horton

📖 💡 🤔
Richard Kotze (mobile)
Richard Kotze (mobile)

📖
Brahian E. Soto Mercedes
Brahian E. Soto Mercedes

📖
Benoit de La Forest
Benoit de La Forest

📖
Salah
Salah

💻 ⚠️
Adam Gordon
Adam Gordon

🐛 💻
Matija Marohnić
Matija Marohnić

📖
Justice Mba
Justice Mba

📖
Mark Pollmann
Mark Pollmann

📖
Ehtesham Kafeel
Ehtesham Kafeel

💻 📖
Julio Pavón
Julio Pavón

💻
Duncan L
Duncan L

📖 💡
Tiago Almeida
Tiago Almeida

📖
Robert Smith
Robert Smith

🐛
Zach Green
Zach Green

📖
dadamssg
dadamssg

📖
Yazan Aabed
Yazan Aabed

📝
Tim
Tim

🐛 💻 📖 ⚠️
Divyanshu Maithani
Divyanshu Maithani

📹
Deepak Grover
Deepak Grover

📹
Eyal Cohen
Eyal Cohen

📖
Peter Makowski
Peter Makowski

📖
Michiel Nuyts
Michiel Nuyts

📖
Joe Ng'ethe
Joe Ng'ethe

💻 📖
Kate
Kate

📖
Sean
Sean

📖
James Long
James Long

🤔 📦
Herb Hagely
Herb Hagely

💡
Alex Wendte
Alex Wendte

💡
Monica Powell
Monica Powell

📖
Vitaly Sivkov
Vitaly Sivkov

💻
Weyert de Boer
Weyert de Boer

🤔 👀 🎨
EstebanMarin
EstebanMarin

📖
Victor Martins
Victor Martins

📖
Royston Shufflebotham
Royston Shufflebotham

🐛 📖 💡
chrbala
chrbala

💻
Donavon West
Donavon West

💻 📖 🤔 ⚠️
Richard Maisano
Richard Maisano

💻
Marco Biedermann
Marco Biedermann

💻 🚧 ⚠️
Alex Zherdev
Alex Zherdev

🐛 💻
André Matulionis dos Santos
André Matulionis dos Santos

💻 💡 ⚠️
Daniel K.
Daniel K.

🐛 💻 🤔 ⚠️ 👀
mohamedmagdy17593
mohamedmagdy17593

💻
Loren ☺️
Loren ☺️

📖
MarkFalconbridge
MarkFalconbridge

🐛 💻
Vinicius
Vinicius

📖 💡
Peter Schyma
Peter Schyma

💻
Ian Schmitz
Ian Schmitz

📖
Joel Marcotte
Joel Marcotte

🐛 ⚠️ 💻
Alejandro Dustet
Alejandro Dustet

🐛
Brandon Carroll
Brandon Carroll

📖
Lucas Machado
Lucas Machado

📖
Pascal Duez
Pascal Duez

📦
Minh Nguyen
Minh Nguyen

💻
LiaoJimmy
LiaoJimmy

📖
Sunil Pai
Sunil Pai

💻 ⚠️
Dan Abramov
Dan Abramov

👀
Christian Murphy
Christian Murphy

🚇
Ivakhnenko Dmitry
Ivakhnenko Dmitry

💻
James George
James George

📖
João Fernandes
João Fernandes

📖
Alejandro Perea
Alejandro Perea

👀
Nick McCurdy
Nick McCurdy

👀 💬 🚇
Sebastian Silbermann
Sebastian Silbermann

👀
Adrià Fontcuberta
Adrià Fontcuberta

👀 📖
John Reilly
John Reilly

👀
Michaël De Boey
Michaël De Boey

👀 💻
Tim Yates
Tim Yates

👀
Brian Donovan
Brian Donovan

💻
Noam Gabriel Jacobson
Noam Gabriel Jacobson

📖
Ronald van der Kooij
Ronald van der Kooij

⚠️ 💻
Aayush Rajvanshi
Aayush Rajvanshi

📖
Ely Alamillo
Ely Alamillo

💻 ⚠️
Daniel Afonso
Daniel Afonso

💻 ⚠️
Laurens Bosscher
Laurens Bosscher

💻
Sakito Mukai
Sakito Mukai

📖
Türker Teke
Türker Teke

📖
Zach Brogan
Zach Brogan

💻 ⚠️
Ryota Murakami
Ryota Murakami

📖
Michael Hottman
Michael Hottman

🤔
Steven Fitzpatrick
Steven Fitzpatrick

🐛
Juan Je García
Juan Je García

📖
Championrunner
Championrunner

📖
Sam Tsai
Sam Tsai

💻 ⚠️ 📖
Christian Rackerseder
Christian Rackerseder

💻
Andrei Picus
Andrei Picus

🐛 👀
Artem Zakharchenko
Artem Zakharchenko

📖
Michael
Michael

📖
Braden Lee
Braden Lee

📖
Kamran Ayub
Kamran Ayub

💻 ⚠️
Matan Borenkraout
Matan Borenkraout

💻
Ryan Bigg
Ryan Bigg

🚧
Anton Halim
Anton Halim

📖
Artem Malko
Artem Malko

💻
Gerrit Alex
Gerrit Alex

💻
Karthick Raja
Karthick Raja

💻
Abdelrahman Ashraf
Abdelrahman Ashraf

💻
Lidor Avitan
Lidor Avitan

📖
Jordan Harband
Jordan Harband

👀 🤔
Marco Moretti
Marco Moretti

💻
sanchit121
sanchit121

🐛 💻
Solufa
Solufa

🐛 💻
Ari Perkkiö
Ari Perkkiö

⚠️
Johannes Ewald
Johannes Ewald

💻
Angus J. Pope
Angus J. Pope

📖
Dominik Lesch
Dominik Lesch

📖
Marcos Gómez
Marcos Gómez

📖
Akash Shyam
Akash Shyam

🐛
Fabian Meumertzheim
Fabian Meumertzheim

💻 🐛
Sebastian Malton
Sebastian Malton

🐛 💻
Martin Böttcher
Martin Böttcher

💻
Dominik Dorfmeister
Dominik Dorfmeister

💻
Stephen Sauceda
Stephen Sauceda

📖
- - - - - - -This project follows the [all-contributors][all-contributors] specification. -Contributions of any kind welcome! - -## LICENSE - -[MIT](LICENSE) - - - -[npm]: https://www.npmjs.com/ -[yarn]: https://classic.yarnpkg.com -[node]: https://nodejs.org -[build-badge]: https://img.shields.io/github/workflow/status/testing-library/react-testing-library/validate?logo=github&style=flat-square -[build]: https://github.com/testing-library/react-testing-library/actions?query=workflow%3Avalidate -[coverage-badge]: https://img.shields.io/codecov/c/github/testing-library/react-testing-library.svg?style=flat-square -[coverage]: https://codecov.io/github/testing-library/react-testing-library -[version-badge]: https://img.shields.io/npm/v/@testing-library/react.svg?style=flat-square -[package]: https://www.npmjs.com/package/@testing-library/react -[downloads-badge]: https://img.shields.io/npm/dm/@testing-library/react.svg?style=flat-square -[npmtrends]: http://www.npmtrends.com/@testing-library/react -[license-badge]: https://img.shields.io/npm/l/@testing-library/react.svg?style=flat-square -[license]: https://github.com/testing-library/react-testing-library/blob/main/LICENSE -[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square -[prs]: http://makeapullrequest.com -[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square -[coc]: https://github.com/testing-library/react-testing-library/blob/main/CODE_OF_CONDUCT.md -[github-watch-badge]: https://img.shields.io/github/watchers/testing-library/react-testing-library.svg?style=social -[github-watch]: https://github.com/testing-library/react-testing-library/watchers -[github-star-badge]: https://img.shields.io/github/stars/testing-library/react-testing-library.svg?style=social -[github-star]: https://github.com/testing-library/react-testing-library/stargazers -[twitter]: https://twitter.com/intent/tweet?text=Check%20out%20react-testing-library%20by%20%40@TestingLib%20https%3A%2F%2Fgithub.com%2Ftesting-library%2Freact-testing-library%20%F0%9F%91%8D -[twitter-badge]: https://img.shields.io/twitter/url/https/github.com/testing-library/react-testing-library.svg?style=social -[emojis]: https://github.com/all-contributors/all-contributors#emoji-key -[all-contributors]: https://github.com/all-contributors/all-contributors -[all-contributors-badge]: https://img.shields.io/github/all-contributors/testing-library/react-testing-library?color=orange&style=flat-square -[guiding-principle]: https://twitter.com/kentcdodds/status/977018512689455106 -[bugs]: https://github.com/testing-library/react-testing-library/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Acreated-desc -[requests]: https://github.com/testing-library/react-testing-library/issues?q=is%3Aissue+sort%3Areactions-%2B1-desc+label%3Aenhancement+is%3Aopen -[good-first-issue]: https://github.com/testing-library/react-testing-library/issues?utf8=✓&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3A"good+first+issue"+ -[discord-badge]: https://img.shields.io/discord/723559267868737556.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square -[discord]: https://discord.gg/testing-library -[stackoverflow]: https://stackoverflow.com/questions/tagged/react-testing-library -[react-hooks-testing-library]: https://github.com/testing-library/react-hooks-testing-library - - diff --git a/README_v1.md b/README_v1.md new file mode 100644 index 00000000..45324901 --- /dev/null +++ b/README_v1.md @@ -0,0 +1,689 @@ +
+

React Testing Library

+ + + goat + + +

Simple and complete React DOM testing utilities that encourage good testing +practices.

+ +
+ +[**Read The Docs**](https://testing-library.com/react) | +[Edit the docs](https://github.com/testing-library/testing-library-docs) + +
+
+ +
+ + +[![Build Status][build-badge]][build] +[![Code Coverage][coverage-badge]][coverage] +[![version][version-badge]][package] +[![downloads][downloads-badge]][npmtrends] +[![MIT License][license-badge]][license] +[![All Contributors][all-contributors-badge]](#contributors) +[![PRs Welcome][prs-badge]][prs] +[![Code of Conduct][coc-badge]][coc] +[![Discord][discord-badge]][discord] + +[![Watch on GitHub][github-watch-badge]][github-watch] +[![Star on GitHub][github-star-badge]][github-star] +[![Tweet][twitter-badge]][twitter] + + +
+ + TestingJavaScript.com Learn the smart, efficient way to test any JavaScript application. + +
+ +## Table of Contents + + + + +- [The problem](#the-problem) +- [The solution](#the-solution) +- [Installation](#installation) + - [Suppressing unnecessary warnings on React DOM 16.8](#suppressing-unnecessary-warnings-on-react-dom-168) +- [Examples](#examples) + - [Basic Example](#basic-example) + - [Complex Example](#complex-example) + - [More Examples](#more-examples) +- [Hooks](#hooks) +- [Guiding Principles](#guiding-principles) +- [Docs](#docs) +- [Issues](#issues) + - [🐛 Bugs](#-bugs) + - [💡 Feature Requests](#-feature-requests) + - [❓ Questions](#-questions) +- [Contributors](#contributors) +- [LICENSE](#license) + + + +## The problem + +You want to write maintainable tests for your React components. As a part of +this goal, you want your tests to avoid including implementation details of your +components and rather focus on making your tests give you the confidence for +which they are intended. As part of this, you want your testbase to be +maintainable in the long run so refactors of your components (changes to +implementation but not functionality) don't break your tests and slow you and +your team down. + +## The solution + +The `React Testing Library` is a very lightweight solution for testing React +components. It provides light utility functions on top of `react-dom` and +`react-dom/test-utils`, in a way that encourages better testing practices. Its +primary guiding principle is: + +> [The more your tests resemble the way your software is used, the more +> confidence they can give you.][guiding-principle] + +## Installation + +This module is distributed via [npm][npm] which is bundled with [node][node] and +should be installed as one of your project's `devDependencies`: + +``` +npm install --save-dev @testing-library/react +``` + +or + +for installation via [yarn][yarn] + +``` +yarn add --dev @testing-library/react +``` + +This library has `peerDependencies` listings for `react` and `react-dom`. + +_React Testing Library versions 13+ require React v18. If your project uses an +older version of React, be sure to install version 12:_ + +``` +npm install --save-dev @testing-library/react@12 + + +yarn add --dev @testing-library/react@12 +``` + +You may also be interested in installing `@testing-library/jest-dom` so you can +use [the custom jest matchers](https://github.com/testing-library/jest-dom). + +> [**Docs**](https://testing-library.com/react) + +### Suppressing unnecessary warnings on React DOM 16.8 + +There is a known compatibility issue with React DOM 16.8 where you will see the +following warning: + +``` +Warning: An update to ComponentName inside a test was not wrapped in act(...). +``` + +If you cannot upgrade to React DOM 16.9, you may suppress the warnings by adding +the following snippet to your test configuration +([learn more](https://github.com/testing-library/react-testing-library/issues/281)): + +```js +// this is just a little hack to silence a warning that we'll get until we +// upgrade to 16.9. See also: https://github.com/facebook/react/pull/14853 +const originalError = console.error +beforeAll(() => { + console.error = (...args) => { + if (/Warning.*not wrapped in act/.test(args[0])) { + return + } + originalError.call(console, ...args) + } +}) + +afterAll(() => { + console.error = originalError +}) +``` + +## Examples + +### Basic Example + +```jsx +// hidden-message.js +import * as React from 'react' + +// NOTE: React Testing Library works well with React Hooks and classes. +// Your tests will be the same regardless of how you write your components. +function HiddenMessage({children}) { + const [showMessage, setShowMessage] = React.useState(false) + return ( +
+ + setShowMessage(e.target.checked)} + checked={showMessage} + /> + {showMessage ? children : null} +
+ ) +} + +export default HiddenMessage +``` + +```jsx +// __tests__/hidden-message.js +// these imports are something you'd normally configure Jest to import for you +// automatically. Learn more in the setup docs: https://testing-library.com/docs/react-testing-library/setup#cleanup +import '@testing-library/jest-dom' +// NOTE: jest-dom adds handy assertions to Jest and is recommended, but not required + +import * as React from 'react' +import {render, fireEvent, screen} from '@testing-library/react' +import HiddenMessage from '../hidden-message' + +test('shows the children when the checkbox is checked', () => { + const testMessage = 'Test Message' + render({testMessage}) + + // query* functions will return the element or null if it cannot be found + // get* functions will return the element or throw an error if it cannot be found + expect(screen.queryByText(testMessage)).toBeNull() + + // the queries can accept a regex to make your selectors more resilient to content tweaks and changes. + fireEvent.click(screen.getByLabelText(/show/i)) + + // .toBeInTheDocument() is an assertion that comes from jest-dom + // otherwise you could use .toBeDefined() + expect(screen.getByText(testMessage)).toBeInTheDocument() +}) +``` + +### Complex Example + +```jsx +// login.js +import * as React from 'react' + +function Login() { + const [state, setState] = React.useReducer((s, a) => ({...s, ...a}), { + resolved: false, + loading: false, + error: null, + }) + + function handleSubmit(event) { + event.preventDefault() + const {usernameInput, passwordInput} = event.target.elements + + setState({loading: true, resolved: false, error: null}) + + window + .fetch('/api/login', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + username: usernameInput.value, + password: passwordInput.value, + }), + }) + .then(r => r.json().then(data => (r.ok ? data : Promise.reject(data)))) + .then( + user => { + setState({loading: false, resolved: true, error: null}) + window.localStorage.setItem('token', user.token) + }, + error => { + setState({loading: false, resolved: false, error: error.message}) + }, + ) + } + + return ( +
+
+
+ + +
+
+ + +
+ +
+ {state.error ?
{state.error}
: null} + {state.resolved ? ( +
Congrats! You're signed in!
+ ) : null} +
+ ) +} + +export default Login +``` + +```jsx +// __tests__/login.js +// again, these first two imports are something you'd normally handle in +// your testing framework configuration rather than importing them in every file. +import '@testing-library/jest-dom' +import * as React from 'react' +// import API mocking utilities from Mock Service Worker. +import {rest} from 'msw' +import {setupServer} from 'msw/node' +// import testing utilities +import {render, fireEvent, screen} from '@testing-library/react' +import Login from '../login' + +const fakeUserResponse = {token: 'fake_user_token'} +const server = setupServer( + rest.post('/api/login', (req, res, ctx) => { + return res(ctx.json(fakeUserResponse)) + }), +) + +beforeAll(() => server.listen()) +afterEach(() => { + server.resetHandlers() + window.localStorage.removeItem('token') +}) +afterAll(() => server.close()) + +test('allows the user to login successfully', async () => { + render() + + // fill out the form + fireEvent.change(screen.getByLabelText(/username/i), { + target: {value: 'chuck'}, + }) + fireEvent.change(screen.getByLabelText(/password/i), { + target: {value: 'norris'}, + }) + + fireEvent.click(screen.getByText(/submit/i)) + + // just like a manual tester, we'll instruct our test to wait for the alert + // to show up before continuing with our assertions. + const alert = await screen.findByRole('alert') + + // .toHaveTextContent() comes from jest-dom's assertions + // otherwise you could use expect(alert.textContent).toMatch(/congrats/i) + // but jest-dom will give you better error messages which is why it's recommended + expect(alert).toHaveTextContent(/congrats/i) + expect(window.localStorage.getItem('token')).toEqual(fakeUserResponse.token) +}) + +test('handles server exceptions', async () => { + // mock the server error response for this test suite only. + server.use( + rest.post('/api/login', (req, res, ctx) => { + return res(ctx.status(500), ctx.json({message: 'Internal server error'})) + }), + ) + + render() + + // fill out the form + fireEvent.change(screen.getByLabelText(/username/i), { + target: {value: 'chuck'}, + }) + fireEvent.change(screen.getByLabelText(/password/i), { + target: {value: 'norris'}, + }) + + fireEvent.click(screen.getByText(/submit/i)) + + // wait for the error message + const alert = await screen.findByRole('alert') + + expect(alert).toHaveTextContent(/internal server error/i) + expect(window.localStorage.getItem('token')).toBeNull() +}) +``` + +> We recommend using [Mock Service Worker](https://github.com/mswjs/msw) library +> to declaratively mock API communication in your tests instead of stubbing +> `window.fetch`, or relying on third-party adapters. + +### More Examples + +> We're in the process of moving examples to the +> [docs site](https://testing-library.com/docs/example-codesandbox) + +You'll find runnable examples of testing with different libraries in +[the `react-testing-library-examples` codesandbox](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples). +Some included are: + +- [`react-redux`](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples/tree/main/?fontsize=14&module=%2Fsrc%2F__tests__%2Freact-redux.js&previewwindow=tests) +- [`react-router`](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples/tree/main/?fontsize=14&module=%2Fsrc%2F__tests__%2Freact-router.js&previewwindow=tests) +- [`react-context`](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples/tree/main/?fontsize=14&module=%2Fsrc%2F__tests__%2Freact-context.js&previewwindow=tests) + +You can also find React Testing Library examples at +[react-testing-examples.com](https://react-testing-examples.com/jest-rtl/). + +## Hooks + +If you are interested in testing a custom hook, check out [React Hooks Testing +Library][react-hooks-testing-library]. + +> NOTE: it is not recommended to test single-use custom hooks in isolation from +> the components where it's being used. It's better to test the component that's +> using the hook rather than the hook itself. The `React Hooks Testing Library` +> is intended to be used for reusable hooks/libraries. + +## Guiding Principles + +> [The more your tests resemble the way your software is used, the more +> confidence they can give you.][guiding-principle] + +We try to only expose methods and utilities that encourage you to write tests +that closely resemble how your React components are used. + +Utilities are included in this project based on the following guiding +principles: + +1. If it relates to rendering components, it deals with DOM nodes rather than + component instances, nor should it encourage dealing with component + instances. +2. It should be generally useful for testing individual React components or + full React applications. While this library is focused on `react-dom`, + utilities could be included even if they don't directly relate to + `react-dom`. +3. Utility implementations and APIs should be simple and flexible. + +Most importantly, we want React Testing Library to be pretty light-weight, +simple, and easy to understand. + +## Docs + +[**Read The Docs**](https://testing-library.com/react) | +[Edit the docs](https://github.com/testing-library/testing-library-docs) + +## Issues + +Looking to contribute? Look for the [Good First Issue][good-first-issue] label. + +### 🐛 Bugs + +Please file an issue for bugs, missing documentation, or unexpected behavior. + +[**See Bugs**][bugs] + +### 💡 Feature Requests + +Please file an issue to suggest new features. Vote on feature requests by adding +a 👍. This helps maintainers prioritize what to work on. + +[**See Feature Requests**][requests] + +### ❓ Questions + +For questions related to using the library, please visit a support community +instead of filing an issue on GitHub. + +- [Discord][discord] +- [Stack Overflow][stackoverflow] + +## Contributors + +Thanks goes to these people ([emoji key][emojis]): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Kent C. Dodds
Kent C. Dodds

💻 📖 🚇 ⚠️
Ryan Castner
Ryan Castner

📖
Daniel Sandiego
Daniel Sandiego

💻
Paweł Mikołajczyk
Paweł Mikołajczyk

💻
Alejandro Ñáñez Ortiz
Alejandro Ñáñez Ortiz

📖
Matt Parrish
Matt Parrish

🐛 💻 📖 ⚠️
Justin Hall
Justin Hall

📦
Anto Aravinth
Anto Aravinth

💻 ⚠️ 📖
Jonah Moses
Jonah Moses

📖
Łukasz Gandecki
Łukasz Gandecki

💻 ⚠️ 📖
Ivan Babak
Ivan Babak

🐛 🤔
Jesse Day
Jesse Day

💻
Ernesto García
Ernesto García

💬 💻 📖
Josef Maxx Blake
Josef Maxx Blake

💻 📖 ⚠️
Michal Baranowski
Michal Baranowski

📝
Arthur Puthin
Arthur Puthin

📖
Thomas Chia
Thomas Chia

💻 📖
Thiago Galvani
Thiago Galvani

📖
Christian
Christian

⚠️
Alex Krolick
Alex Krolick

💬 📖 💡 🤔
Johann Hubert Sonntagbauer
Johann Hubert Sonntagbauer

💻 📖 ⚠️
Maddi Joyce
Maddi Joyce

💻
Ryan Vice
Ryan Vice

📖
Ian Wilson
Ian Wilson

📝
Daniel
Daniel

🐛 💻
Giorgio Polvara
Giorgio Polvara

🐛 🤔
John Gozde
John Gozde

💻
Sam Horton
Sam Horton

📖 💡 🤔
Richard Kotze (mobile)
Richard Kotze (mobile)

📖
Brahian E. Soto Mercedes
Brahian E. Soto Mercedes

📖
Benoit de La Forest
Benoit de La Forest

📖
Salah
Salah

💻 ⚠️
Adam Gordon
Adam Gordon

🐛 💻
Matija Marohnić
Matija Marohnić

📖
Justice Mba
Justice Mba

📖
Mark Pollmann
Mark Pollmann

📖
Ehtesham Kafeel
Ehtesham Kafeel

💻 📖
Julio Pavón
Julio Pavón

💻
Duncan L
Duncan L

📖 💡
Tiago Almeida
Tiago Almeida

📖
Robert Smith
Robert Smith

🐛
Zach Green
Zach Green

📖
dadamssg
dadamssg

📖
Yazan Aabed
Yazan Aabed

📝
Tim
Tim

🐛 💻 📖 ⚠️
Divyanshu Maithani
Divyanshu Maithani

📹
Deepak Grover
Deepak Grover

📹
Eyal Cohen
Eyal Cohen

📖
Peter Makowski
Peter Makowski

📖
Michiel Nuyts
Michiel Nuyts

📖
Joe Ng'ethe
Joe Ng'ethe

💻 📖
Kate
Kate

📖
Sean
Sean

📖
James Long
James Long

🤔 📦
Herb Hagely
Herb Hagely

💡
Alex Wendte
Alex Wendte

💡
Monica Powell
Monica Powell

📖
Vitaly Sivkov
Vitaly Sivkov

💻
Weyert de Boer
Weyert de Boer

🤔 👀 🎨
EstebanMarin
EstebanMarin

📖
Victor Martins
Victor Martins

📖
Royston Shufflebotham
Royston Shufflebotham

🐛 📖 💡
chrbala
chrbala

💻
Donavon West
Donavon West

💻 📖 🤔 ⚠️
Richard Maisano
Richard Maisano

💻
Marco Biedermann
Marco Biedermann

💻 🚧 ⚠️
Alex Zherdev
Alex Zherdev

🐛 💻
André Matulionis dos Santos
André Matulionis dos Santos

💻 💡 ⚠️
Daniel K.
Daniel K.

🐛 💻 🤔 ⚠️ 👀
mohamedmagdy17593
mohamedmagdy17593

💻
Loren ☺️
Loren ☺️

📖
MarkFalconbridge
MarkFalconbridge

🐛 💻
Vinicius
Vinicius

📖 💡
Peter Schyma
Peter Schyma

💻
Ian Schmitz
Ian Schmitz

📖
Joel Marcotte
Joel Marcotte

🐛 ⚠️ 💻
Alejandro Dustet
Alejandro Dustet

🐛
Brandon Carroll
Brandon Carroll

📖
Lucas Machado
Lucas Machado

📖
Pascal Duez
Pascal Duez

📦
Minh Nguyen
Minh Nguyen

💻
LiaoJimmy
LiaoJimmy

📖
Sunil Pai
Sunil Pai

💻 ⚠️
Dan Abramov
Dan Abramov

👀
Christian Murphy
Christian Murphy

🚇
Ivakhnenko Dmitry
Ivakhnenko Dmitry

💻
James George
James George

📖
João Fernandes
João Fernandes

📖
Alejandro Perea
Alejandro Perea

👀
Nick McCurdy
Nick McCurdy

👀 💬 🚇
Sebastian Silbermann
Sebastian Silbermann

👀
Adrià Fontcuberta
Adrià Fontcuberta

👀 📖
John Reilly
John Reilly

👀
Michaël De Boey
Michaël De Boey

👀 💻
Tim Yates
Tim Yates

👀
Brian Donovan
Brian Donovan

💻
Noam Gabriel Jacobson
Noam Gabriel Jacobson

📖
Ronald van der Kooij
Ronald van der Kooij

⚠️ 💻
Aayush Rajvanshi
Aayush Rajvanshi

📖
Ely Alamillo
Ely Alamillo

💻 ⚠️
Daniel Afonso
Daniel Afonso

💻 ⚠️
Laurens Bosscher
Laurens Bosscher

💻
Sakito Mukai
Sakito Mukai

📖
Türker Teke
Türker Teke

📖
Zach Brogan
Zach Brogan

💻 ⚠️
Ryota Murakami
Ryota Murakami

📖
Michael Hottman
Michael Hottman

🤔
Steven Fitzpatrick
Steven Fitzpatrick

🐛
Juan Je García
Juan Je García

📖
Championrunner
Championrunner

📖
Sam Tsai
Sam Tsai

💻 ⚠️ 📖
Christian Rackerseder
Christian Rackerseder

💻
Andrei Picus
Andrei Picus

🐛 👀
Artem Zakharchenko
Artem Zakharchenko

📖
Michael
Michael

📖
Braden Lee
Braden Lee

📖
Kamran Ayub
Kamran Ayub

💻 ⚠️
Matan Borenkraout
Matan Borenkraout

💻
Ryan Bigg
Ryan Bigg

🚧
Anton Halim
Anton Halim

📖
Artem Malko
Artem Malko

💻
Gerrit Alex
Gerrit Alex

💻
Karthick Raja
Karthick Raja

💻
Abdelrahman Ashraf
Abdelrahman Ashraf

💻
Lidor Avitan
Lidor Avitan

📖
Jordan Harband
Jordan Harband

👀 🤔
Marco Moretti
Marco Moretti

💻
sanchit121
sanchit121

🐛 💻
Solufa
Solufa

🐛 💻
Ari Perkkiö
Ari Perkkiö

⚠️
Johannes Ewald
Johannes Ewald

💻
Angus J. Pope
Angus J. Pope

📖
Dominik Lesch
Dominik Lesch

📖
Marcos Gómez
Marcos Gómez

📖
Akash Shyam
Akash Shyam

🐛
Fabian Meumertzheim
Fabian Meumertzheim

💻 🐛
Sebastian Malton
Sebastian Malton

🐛 💻
Martin Böttcher
Martin Böttcher

💻
Dominik Dorfmeister
Dominik Dorfmeister

💻
Stephen Sauceda
Stephen Sauceda

📖
+ + + + + + +This project follows the [all-contributors][all-contributors] specification. +Contributions of any kind welcome! + +## LICENSE + +[MIT](LICENSE) + + + +[npm]: https://www.npmjs.com/ +[yarn]: https://classic.yarnpkg.com +[node]: https://nodejs.org +[build-badge]: https://img.shields.io/github/workflow/status/testing-library/react-testing-library/validate?logo=github&style=flat-square +[build]: https://github.com/testing-library/react-testing-library/actions?query=workflow%3Avalidate +[coverage-badge]: https://img.shields.io/codecov/c/github/testing-library/react-testing-library.svg?style=flat-square +[coverage]: https://codecov.io/github/testing-library/react-testing-library +[version-badge]: https://img.shields.io/npm/v/@testing-library/react.svg?style=flat-square +[package]: https://www.npmjs.com/package/@testing-library/react +[downloads-badge]: https://img.shields.io/npm/dm/@testing-library/react.svg?style=flat-square +[npmtrends]: http://www.npmtrends.com/@testing-library/react +[license-badge]: https://img.shields.io/npm/l/@testing-library/react.svg?style=flat-square +[license]: https://github.com/testing-library/react-testing-library/blob/main/LICENSE +[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square +[prs]: http://makeapullrequest.com +[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square +[coc]: https://github.com/testing-library/react-testing-library/blob/main/CODE_OF_CONDUCT.md +[github-watch-badge]: https://img.shields.io/github/watchers/testing-library/react-testing-library.svg?style=social +[github-watch]: https://github.com/testing-library/react-testing-library/watchers +[github-star-badge]: https://img.shields.io/github/stars/testing-library/react-testing-library.svg?style=social +[github-star]: https://github.com/testing-library/react-testing-library/stargazers +[twitter]: https://twitter.com/intent/tweet?text=Check%20out%20react-testing-library%20by%20%40@TestingLib%20https%3A%2F%2Fgithub.com%2Ftesting-library%2Freact-testing-library%20%F0%9F%91%8D +[twitter-badge]: https://img.shields.io/twitter/url/https/github.com/testing-library/react-testing-library.svg?style=social +[emojis]: https://github.com/all-contributors/all-contributors#emoji-key +[all-contributors]: https://github.com/all-contributors/all-contributors +[all-contributors-badge]: https://img.shields.io/github/all-contributors/testing-library/react-testing-library?color=orange&style=flat-square +[guiding-principle]: https://twitter.com/kentcdodds/status/977018512689455106 +[bugs]: https://github.com/testing-library/react-testing-library/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Acreated-desc +[requests]: https://github.com/testing-library/react-testing-library/issues?q=is%3Aissue+sort%3Areactions-%2B1-desc+label%3Aenhancement+is%3Aopen +[good-first-issue]: https://github.com/testing-library/react-testing-library/issues?utf8=✓&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3A"good+first+issue"+ +[discord-badge]: https://img.shields.io/discord/723559267868737556.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square +[discord]: https://discord.gg/testing-library +[stackoverflow]: https://stackoverflow.com/questions/tagged/react-testing-library +[react-hooks-testing-library]: https://github.com/testing-library/react-hooks-testing-library + +