Skip to content

测试运行器

jest https://jestjs.io/zh-Hans/

出自 facebook 针对 react 做了优化,cra 已集成

dom 、react 组件 测试库

enzyme https://enzymejs.github.io/enzyme/ 发布很早流行 dom 测试库 yarn add enzyme jest-enzyme enzyme-adapter-react-16

testing-library https://testing-library.com/docs/intro 新发布的 dom 测试库 yarn add @testing-library/react @testing-library/jest-dom

下载量对比:https://www.npmtrends.com/@testing-library/react-vs-enzyme

✔️ testing-library 更活跃,使用简单,有针对的 hooks 的周边 @testing-library/react-hooks

当然,两者也可以同时使用

yarn add react-test-renderer 快照测试

测试开发简介

  • yarn test 只运行与上次 git 提交不同的文件
  • 命名约定: tests 文件夹中带有 .js 后缀的文件,.test.js .spec.js 后缀的文件,放于被测试的文件旁边
  • 不必使用 ts ,因为机会用不到类型,而且 jest 对 ts 支持也不太完善

渲染组件 render(<App />)

js
import { render, screen } from '@testing-library/react'
render(<App />)

'debug', 'container', 'baseElement', 'unmount', 'rerender', 'asFragment',

选择元素(返回 DOM 元素)

getByRole 可查询所有元素 getByLabelText 查找表单 getByPlaceholderText 查找 Placeholder getByDisplayValue 表单元素的当前值 getByText 除表单外的其他元素 getByTestId 没有其他办法就用这个查找 getByTitle getByAltText

  • getBy 查找不存在的元素时,会引发错误。而 queryBy 不会,用于否定判断。 findBy 用于异步渲染组件测试,返回 promise,await 等待界面最终呈现,用于异步渲染测试

    总结:对于任何尚未存在但最终会存在的元素,请使用 findBy 而不是 getBy 或 queryBy。如果为缺少的元素断言,请使用 queryBy。否则默认为 getBy

  • 查找多个元素 getAllBy queryAllBy findAllBy

断言

interface Matchers<R, T = {}> 参阅该接口下的方法

触发事件

js
// 建立在 fireEvent 之上,更能模仿实际用户在浏览器上的行为
import userEvent from '@testing-library/user-event'
userEvent.click(screen.getByText('请求触发'))

回调函数

js
const onChange = jest.fn() // 模拟函数
expect(onChange).toHaveBeenCalledTimes(5) // 模拟函数被调用的次数

异步请求

js
jest.mock('axios') // 确保已对请求库进行模拟
// 模拟网络请求响应
axios.get.mockImplementationOnce(() => Promise.resolve({ data: { hits: stories } }))

快照测试

yarn add react-test-renderer 首次执行会生成一个 html 快照存在本地,下次执行测试时,会与本地快照进行对比,如有变化则测试失败

js
import renderer from 'react-test-renderer'

test('快照测试', () => {
  const component = renderer.create(<Search />)
  let tree = component.toJSON()
  expect(tree).toMatchSnapshot()
})

自定义的 hooks 测试

因为 hooks 必须在函数组件内使用,而 @testing-library/react-hooks 提供了在真实组件内使用 hooks 的测试体验,从而可以独立对 hooks 进行测试

例子:

js
import { renderHook } from '@testing-library/react-hooks'

test('测试 hooks', () => {
  const cb = jest.fn()
  renderHook(() => useBeforeMount(cb))
  expect(cb).toBeCalledTimes(1)
})