简介

react-testing-library 是一个用于测试 React 组件的库,其方式类似于最终用户使用组件的方式。它非常适合 React 组件和应用程序的单元测试、集成和 e2e 测试。它更直接地与 DOM 节点一起使用,因此建议与 jest-dom 一起使用,这样可以方便的做断言。

react-testing-library 可以取代enzyme库与jest结合来对react组件进行测试。
本文参考地址:

官网地址:

配置

安装

npm install --save @testing-library/react @testing-library/jest-dom

yarn add @testing-library/react

yarn add @testing-library/jest-dom

全局配置(结合jest.config.js使用)

tests/setupTests.js 中引入的全局的配置:

// react-testing-library 将您的组件显示为document.body,
// 这将为 jest-dom 添加一个自定义断言
import '@testing-library/jest-dom';

基础

渲染组件

renderrender(<App />)函数渲染组件。您应该可以在测试中访问React组件。同时使用screen.debug();在运行测试文件时,命令行中会输出已经渲染的组件html结构。

选择元素

搜索类型
screen.getByText

screen.getByText('Search:'); 通过文本来选择元素。

getByText如果找不到元素,默认情况下会方便地引发错误。因此无需写显示断言。

getByText函数接受一个字符串作为输入,也接受一个正则表达式。字符串参数用于完全匹配,而正则表达式可用于部分匹配。

screen.getByRole

getByRole函数通常用于通过aria-label属性检索元素,通过它们在React Testing Library中的可访问性角色来选择元素。

通常不必为HTML元素显式分配aria角色,因为DOM已经具有附加到HTML元素的隐式角色,例如input元素。它是getByText的有力竞争者。

语法:getByRole(‘type’,{name:‘name’});

type: 元素类型

name:[aria-label属性名]

扩展

其他的对于特定元素的搜索类型:

  • screen.getByLabelText 与给定匹配的标签,然后找到与该标签关联的元素。
  • screen.getByPlaceholderText
  • screen.getByAltText
  • screen.getByDisplayValue
LabelText: getByLabelText:<label for="search" />
PlaceholderText: getByPlaceholderText:<input placeholder="Search" />
AltText: getByAltText:<img alt="profile" />
DisplayValue: getByDisplayValue:<input value="JavaScript" />
  • screen.getByTestId :getByTestId需要HTML中分配属性data-testid
搜索变体

思考:

何时使用getBy vs queryBy?

​ 当我们断言不存在的元素时使用queryBy

何时使用findBy?

​ findBy搜索变量用于异步元素,这些元素最终会出现。

如何选择多个元素?

​ 所有的搜索变体都可以用All扩展,例 getAllBy\queryAllBy\findAllBy ,它们都返回一个元素数组,并且可以再次与搜索类型相关联。

getBy*

默认的搜索变体,例screen.getByTextscreen.getByRole。这也是测试React组件时默认使用的搜索变体。它返回一个元素或者错误。

queryBy*

screen.queryByText(/Searches for JavaScript/)

跟getBy访问的相同搜索类型进行扩展,如下:

  • queryByText
  • queryByRole
  • queryByLabelText
  • queryByPlaceholderText
  • queryByAltText
  • queryByDisplayValue
findBy*

example:expect(await screen.findByText(/Signed in as/)).toBeInTheDocument();

与getBy访问的相同搜索类型进行扩展,如下

  • findByText
  • findByRole
  • findByLabelText
  • findByPlaceholderText
  • findByAltText
  • findByDisplayValue
选择多个元素

screen.getAllBy*、screen.queryAllBy* 、screen.findAllBy*

返回结果一览表

输出选择元素

screen.debug(screen.getAllBy*/getBy*)

screen.debug(screen.queryAllBy*/queryBy*)

screen.debug(screen.findAllBy*/findBy*)

断言

​ React测试库扩展了jest的api,定义了自己的断言函数,所有的断言函数包含在@testing-library/jest-dom包中。详情:内置断言库

  • toBeDisabled
  • toBeEnabled
  • toBeEmpty
  • toBeEmptyDOMElement
  • toBeInTheDocument
  • toBeInvalid
  • toBeRequired 表单字段必须
  • toBeValid
  • toBeVisible
  • toContainElement
  • toContainHTML
  • toHaveAttribute
  • toHaveClass 有某一个类名
  • toHaveFocus
  • toHaveFormValues
  • toHaveStyle
  • toHaveTextContent
  • toHaveValue
  • toHaveDisplayValue
  • toBeChecked
  • toBePartiallyChecked
  • toHaveDescription

事件

fireEvent

例:

    fireEvent.change(screen.getByRole('textbox'), {
      target: { value: 'JavaScript' },
    });

fireEvent函数接受一个元素(这里是textbox角色的输入字段)和一个事件(这里是一个值为“JavaScript”的事件,此处只触发change事件,并不触发keyDown,keyUp,keyPress事件)。

用户事件

userEvent

例如:

import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
 
import App from './App';
 
describe('App', () => {
  test('renders App component', async () => {
    render(<App />);
 
    // wait for the user to resolve
    await screen.findByText(/Signed in as/);
 
    expect(screen.queryByText(/Searches for JavaScript/)).toBeNull();
 
    await userEvent.type(screen.getByRole('textbox'), 'JavaScript');
 
    expect(
      screen.getByText(/Searches for JavaScript/)
    ).toBeInTheDocument();
  });
});

Whenever possible, use userEvent over fireEvent when using React Testing Library

回调处理程序

使用jest模拟函数模拟回调处理程序,与具体查看jest文档

异步

使用jest模拟请求函数,具体查看jest文档

findBy搜索变量用于异步元素,这些元素最终会出现。可以用它等得某元素的出现,可以使用更为明确的等待promise:await act(() => promise);,

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐