
@testing-library[1] 是一系列建立在 DOM Testing Library[2](@testing-library/dom)基础上的包的集合。用来测试 UI 组件,不鼓励测试实现细节(比如组件内部状态、方法甚至生命周期),而是鼓励从用户使用的角度进行测试。
作为初级教程,篇幅有效,本文只讨论 @testing-library/react[3] 的使用,有其他需求的同学,可以查阅对应框架的使用文档[4]。
-
官网地址:https://testing-library.com/docs/react-testing-library/intro -
repo 地址:https://github.com/testing-library/react-testing-library
@testing-library/react
React Testing Library 在 DOM Testing Library 的基础上构建,通过添加用于处理 React 组件的 API 来增强功能。
为了避免测试组件实现细节,而是专注于以组件使用的方式进行测试,从而方便理解与对组件重构(实现方式变化但功能不变)。@testing-library/react
基于 react-dom
和 react-dom/test-utils
提供了一些轻量级的工具函数。
另外,@testing-library/react
视 Jest[5] 为一等公民,所以默认跟 Jest 配合很好。不过也能自定义使用其他测试框架[6]。
项目准备
Create React App[7] 对 React Testing Library 提供了开箱支持,不过由于各种原因[8],React 官方文档已不再提及,所以我们使用 Next.js 来整合 @testing-library/react
。
Next.js 从 12 开始已经内置了 Jest 支持[9],配置起来非常简单。首先安装依赖:
npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
-
jest-environment-jsdom[10]:Jest 的默认环境是 Node.js 环境[11]。如果正在构建 Web 应用程序,可以使用 jsdom 来代替浏览器类似的环境。要开始使用 JSDOM 测试环境,如果尚未安装,则必须安装 jest-environment-jsdom 软件包 -
@testing-library/jest-dom[12]:提供了一组自定义的 jest 匹配器,你可以使用它们来扩展 jest。比如: .toBeInTheDocument()
。
方便起见,只需在测试设置文件(tests setup file)中导入 @testing-library/jest-dom
,你就可以开始使用了:
import '@testing-library/jest-dom'
在你的项目根目录下创建一个 jest.config.mjs
文件,并添加以下内容:
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
})
// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
// Add more setup options before each test is run
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testEnvironment: 'jest-environment-jsdom',
}
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config)
在幕后,next/jest
会自动为你配置 Jest,包括:
-
使用 SWC 设置 transform -
自动 Mock 样式表( .css
、.module.css
及其 scss 变体)、图像导入和next/font
-
将 .env
(及所有变体)加载到process.env
中 -
从测试解析(test resolving)和 transforms 中忽略 node_modules
-
从测试解析中忽略 .next
-
加载 next.config.js
,寻找启用 SWC transforms 的标志
创建测试文件
向 package.json
文件中添加 test
脚本
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest --watch"
}
}
创建第一个测试文件
你的项目现在已准备好运行测试。按照 Jest 的惯例,在项目根目录下添加 __tests__
文件夹以进行测试。
例如,我们可以添加一个测试来检查 <Home />
组件是否成功渲染标题:
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'
describe('Home', () => {
it('renders a heading', () => {
render(<Home />)
const heading = screen.getByRole('heading', {
name: /welcome to next.js!/i,
})
expect(heading).toBeInTheDocument()
})
})
可选地,添加一个快照测试来跟踪您的 <Home />
组件中的任何意外更改:
import { render } from '@testing-library/react'
import Home from '../pages/index'
it('renders homepage unchanged', () => {
const { container } = render(<Home />)
expect(container).toMatchSnapshot()
})
执行测试
运行 npm run test
来执行测试套件。在你的测试通过或失败后,你会注意到一系列交互式 Jest 命令列表,这些命令将有助于你添加更多的测试。
其他案例
案例一:render
/userEvent
/screen
// import react-testing methods
import {render, screen} from '@testing-library/react'
// userEvent library simulates user interactions by dispatching the events that would happen if the interaction took place in a browser.
import userEvent from '@testing-library/user-event'
// add custom jest matchers from jest-dom
import '@testing-library/jest-dom'
// the component to test
import Fetch from './fetch'
test('loads and displays greeting', async () => {
// Render a React element into the DOM
render(<Fetch url="/greeting" />)
await userEvent.click(screen.getByText('Load Greeting'))
// wait before throwing an error if it cannot find an element
await screen.findByRole('heading')
// assert that the alert message is correct using
// toHaveTextContent, a custom matcher from jest-dom.
expect(screen.getByRole('heading')).toHaveTextContent('hello there')
expect(screen.getByRole('button')).toBeDisabled()
})
完整代码看这里[13]。
案例二:render
import {render} from '@testing-library/react'
import '@testing-library/jest-dom'
test('renders a message', () => {
const {asFragment, getByText} = render(<Greeting />)
expect(getByText('Hello, world!')).toBeInTheDocument()
expect(asFragment()).toMatchInlineSnapshot(`
<h1>Hello, World!</h1>
`)
})
案例三:renderHook
import {renderHook} from '@testing-library/react'
test('returns logged in user', () => {
const {result, rerender} = renderHook((props = {}) => props, {
initialProps: {name: 'Alice'},
})
expect(result.current).toEqual({name: 'Alice'})
rerender()
expect(result.current).toEqual({name: undefined})
})
注意:@testing-library/react
v13.1.0 才增加 renderHook
API 的支持,而且还限定在 React18。 如果你的项目使用 React17-,那么最高只能安装 v12.1.5 版本,测试 React Hook 的话,需要借助 @testing-library/react-hooks
库具体信息看这里的链接[14]。
// React 18, @testing-library/react v13.1.0+
import { renderHook } from '@testing-library/react'
// React 17-, @testing-library/react-hooks
import { renderHook } from '@testing-library/react-hooks'
完整 API 及其他资源
完整 API
由于 @testing-library/react
是基于 @testing-library/dom
的封装,re-export 了 @testing-library/dom
API。因此完整 API 要同时参考 @testing-library/react 的拓展 API[15](render
,renderHook
等)和 @testing-library/dom API[16]。
其他资源
-
Jest 文档[17] -
React Testing Library[18] -
Testing Playground[19] – 如果你不知道该使用什么 API 选择页面元素,可以参考这里的官方推荐
引用链接
@testing-library: https://www.npmjs.com/org/testing-library
[2]
DOM Testing Library: https://testing-library.com/docs/dom-testing-library/intro
[3]
@testing-library/react: https://testing-library.com/docs/react-testing-library/intro
[4]
查阅对应框架的使用文档: https://testing-library.com/docs/dom-testing-library/install
[5]
Jest: https://jestjs.io/
[6]
自定义使用其他测试框架: https://testing-library.com/docs/react-testing-library/setup#using-without-jest
[7]
Create React App: https://create-react-app.dev/
[8]
各种原因: https://www.linkedin.com/pulse/end-era-react-team-longer-recommends-create-app-vivek-dwivedi
[9]
Next.js 从 12 开始已经内置了 Jest 支持: https://nextjs.org/docs/pages/building-your-application/optimizing/testing#setting-up-jest-with-the-rust-compiler
[10]
jest-environment-jsdom: https://jestjs.io/docs/tutorial-jquery
[11]
Jest 的默认环境是 Node.js 环境: https://jestjs.io/docs/configuration#testenvironment-string
[12]
@testing-library/jest-dom: https://www.npmjs.com/package/@testing-library/jest-dom
[13]
看这里: https://testing-library.com/docs/react-testing-library/example-intro#full-example
[14]
看这里的链接: https://github.com/testing-library/react-hooks-testing-library#a-note-about-react-18-support
[15]
@testing-library/react 的拓展 API: https://testing-library.com/docs/react-testing-library/api
[16]
@testing-library/dom API: https://testing-library.com/docs/dom-testing-library/api
[17]
Jest 文档: https://jestjs.io/docs/getting-started
[18]
React Testing Library: https://testing-library.com/docs/react-testing-library/intro/
[19]
Testing Playground: https://testing-playground.com/
原文始发于微信公众号(写代码的宝哥):@testing-library/react: 测试你的 React 组件
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/243957.html