React 搭配Testing Library 实作测试

更新日期: 2024-03-01阅读: 813标签: 测试

本篇使用的JavaScript 框架Jest,所以在开始前要先了解一些Jest 基本语法,才会比较快理解喔!

 

测试库

虽然Jest 本身有提供很多测试方法,但在测试上都比较偏向逻辑测试,像是a + b 是否等于c。而实际上我们所需要的测试有一大部分也包含UI 的测试,像是画面上有没显示正确文字,或是使用者点击有没有跳出视窗等等,这时候就是Testing Library出马的时候了!

它的官网介绍就很明确地告诉你

The @testing-library family of packages helps you test UI components in a user-centric way.

也就是@testing-library 系列的套件可以帮助你以用户为中心的方式测试UI 元件。

Testing Library 不只提供可以共通使用的测试套件,还有专为各个框架所出的套件,基本的三大框架reactvueangular 都有属于他们的测试UI 套件。而比较新的框架像是Preact、Svelte 也都有在持续更新。

 

Testing Libaray For React

以React 来说,搭配Jest 会需要的Testing Libary 有以下几个:

1. @testing-library/react - 模拟React 渲染,Ex:render、screen

2. @testing-library/jest-dom - 扩充jest 的断言库,Ex:toBeInTheDocument、toHaveClass

3. @testing-library/user-event - 模拟使用者操作,Ex:useEvent.click、userEvent.type

接下来来各别介绍这三个的使用时机:

◆ @testing-library/react

主要是提供模拟渲染UI 画面的函式,比较常用的有

1.render()

就如同React 中的render,就是模拟渲染React 元件,假设有一个<Home/>元件:

export const Home = () => {
  return <h1>Home Page</h1>
};

要测试元件的DOM 元素时,就可以使用render()函式。

import { render } from '@testing-library/react'

describe('testing home component', () => {
  it('show Home Page in the home component', () => {
    const {getByText} = render(<Home/>);
    expect(getByText('Home Page')).toBeTruthy(); //使用 getByText 判斷抓到文字的元素是否存在
  });
});

render() 函式会回传一个物件包含一些属性对象:

  • Query:getBy、queryBy、findBy、getAllBy、queryAllBy、findAllBy,取得元件内的元素。

  • container:渲染的DOM 节点。

  • debug:侦错函式,可以显示当前的DOM 结构。

  • rerender:重新渲染元件。

  • unmount:取消渲染。

Query 有很多不同的取元素方法,有get、find、query,各自都有取得多元素的all 方法

Query 种类\结果

没有符合

一项符合大于一个符合是否为非同步函式
getBy...Throw error

回传元素

Throw error
queryBy...回传null

回传元素

Throw error
findBy...Throw error

回传元素

Throw error
getAllBy...Throw error

回传阵列元素

回传阵列元素
queryAllBy...回传[]

回传阵列元素

回传阵列元素
findAllBy...Throw error

回传阵列元素

回传阵列元素

 

看起来很容易搞混,不过他们都有各自使用的时机

  • getBy...:大部分都可以使用,判断元素是否存在。

  • queryBy...:因为找不到会回传null的特性,所以常用来判断元素是否一开始不存在。

  • findBy...:非同步函式,可以判断需等待的元素是否存在,例如api 回传才会显示在画面上。

2.screen()

虽然render()解决了模拟UI 的情况,不过只能根据render()的内容进行测试,如果有多个render()函式测起来就会比较麻烦,这时候就可以使用screen()。

其实screen()算是@testing-library/dom 所提供,而所有框架的@testing-library 底层都有@testing-library/dom,所以这边才可以直接做使用。

而screen()所抓取的元素是<body></body> 内的所有DOM 元素。

import { render, screen } from '@testing-library/react'

describe('testing home component', () => {
  it('show Home Page in the home component', () => {
    render(<Home/>);
    render(<Home/>);
    expect(getAllByText('Home Page')).toBeTruthy(); //使用 getAllByText 一次判斷兩個 Home 元件元素是否存在
  });
});

个人在抓元素时是比较常用  screen()胜过于使用render()回传的方法,使用起来也比较方便。

3.renderHook()

顾名思义就是去模拟客制化的React Hook,假设今天有一个计数器的customhook

import { useState } from 'react';

function useCounter(initialValue = 0) {
  const [count, setCount] = useState(initialValue);

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return { count, increment, decrement };
}

export default useCounter;

要测试这个hook 就可以使用renderHook(),他可以传入两个参数,第一个就是要测试的函式,第二是传入函式的参数(非必要)。

import useCounter from './useCounter';
import { renderHook, act } from '@testing-library/react';

it("should increment and decrement the counter", () => {
  const { result } = renderHook(useCounter);

  expect(result.current.count).toBe(0);

  act(() => {
    result.current.increment(); // 呼叫 + 1 函式
  });

  expect(result.current.count).toBe(1);

  act(() => {
    result.current.decrement(); // 呼叫 -1 函式
  });

  expect(result.current.count).toBe(0);
});

renderHook()会回传一个物件,可以使用result属性利用 result.current去操控函式的回传物件。

如果有更改state的操作,就需要使用act包起来,这样才可以即时更新state的状态。

 

◆ @testing-library/jest-dom

@testing-library/jest-dom 提供给Jest 很多DOM 元素的扩充判断,让我们在抓元素时,有更多的方法去测试,比较常用的像是toBeInTheDocument、toHaveClass等等。

以刚刚的<Home/>渲染测试为例

import { render } from '@testing-library/react'

describe('testing home component', () => {
  it('show Home Page in the home component', () => {
    const {getByText} = render(<Home/>);
    expect(getByText('Home Page')).toBeInTheDocument(); //判斷元素是否存在於 Document
  });
});

或是

import { render } from '@testing-library/react'

describe('testing div', () => {
  it('test div classname is hide', () => {
    render(<div className='hide'>test</div>);
    expect(screen.getByText('test')).toHaveClass('hide'); //判斷元素是否含有指定的 class name
  });
});

 

◆ @testing-library/user-event

最后一个就是模拟使用着操作,user-event 常常跟另一个@testing-library/react 的fireEvent 拿来比较,fireEvent 就是在程式码中会用的事件处理,像是click 或是change,而user-event的底层就是fireEvent,不过userEvent 能更贴合使用者的模拟情况,像是同样是在input 输入文字,如果使用fireEvent 就会使用change 的事件。

fireEvent:

import { fireEvent } from '@testing-library/react';

fireEvent.change(inputElement, { target: { value: 'Hello, world!' } });

不过如果是用userEvent 就会使用type 的事件。

userEvent:

import userEvent from '@testing-library/user-event';

const user = userEvent.setup()
user.type(inputElement, 'Hello, world!');

乍看之下没有什么不一样,不过userEvent 的type 还包含使用者点击input,输入文字的keydown、keyup 事件,比起fireEvent 的change,更贴近实际的使用者操作情况。

除此之外,userEvent 还有提供很多实用的方法像是:

  • dblClick:点击两次

  • tripleClick:点击三次

  • type:input 输入

  • upload:上传

  • hover/unhover:指标移进移出

  • copy/paste:复制/贴上

详细的可以参考User Interactions

链接: https://fly63.com/article/detial/12674

测试工具比较:选Jest,不选Mocha

Jest的未来看起来非常令人激动!看到Jest推陈出新如此快速,我感觉它将很快成为整个React生态系统中大部分项目的首选工具。我建议,应该把测试迁移到Jest上去。

你需要了解的前端测试“金字塔”

如果您正在测试前端应用程序,则应该了解前端测试金字塔。在本文中,我们将看到前端测试金字塔是什么,以及如何使用它来创建全面的测试套件。

web网页性能测试工具都有哪些

作为前端开发,我们不仅需要满足产品需求功能的实现,同时也需要对自己做的网站进行安全、易用性、性能等方面的考虑。随着目前技术不断进步,web页面的性能测试工具也在不断完善,通过这些工具,我们可以客观的评价web网站的质量水平。

js单元测试工具-jest自动化测试

jest 是 facebook 开源的,用来进行单元测试的框架,可以测试 javascipt 和 react。jest 提供了非常方便的 API,可以对下面的场景方便的测试:一般函数、异步函数、测试的生命周期、react 测试

web测试要点、方法_web端测试大全总结

web测试大全,测试web网站有哪些点呢?主要包括:功能测试、兼容性测试、安全测试、输入框测试、用户权限测试等

前端性能测试工具整理简介_性能测试工具都有哪些?

前端性能测试工具都有哪些:Favicon、Open Graph、图片优化-压缩图像、CSS 优化-Autoprefixer、Purifycss、minify CSS、减少载入时间、GZIP、CDN、优化平台-Sentry、Google Tag Manager

不用写代码,也能做好接口测试

本文你将了解到:1、接口测试基本概念,包含什么是接口,什么是接口测试,为什么要做接口测试;2、接口测试用例设计,3、怎样不用写代码,也能快速的根据开发的API文档完成接口自动化测试脚本

Selenium打开浏览器加载慢的原因

在自动化元素定位操作中经常使用智能等待来加强定位的强壮性,主要就是因为WebDriver没有提供页面加载场景的方法;在使用JavaScript知识的突然心生灵感,可以使用JavaScript来配合验证页面加载,结果发现我真是井底之蛙。

power assert_更智能、优雅的全方位 assert 断言库

在写测试代码时,以往我们需要翻阅文档,学习各种 API 才能明白如何操作断言。而现在我们可以透过 power-assert 的 assert 方法来减轻调试压力。不仅如此,它还提供更加直观,具体的运行效果,帮助 DEBUG。写测试代码,其实可以很容易。

常用的web网站负载/压力/性能测试工具

在网站上线发布之前,我们除了必要的安全、功能测试外,往往还需要进行压力测试。通过模拟实际应用的软硬件环境及用户使用过程的系统负荷,长时间或超大负荷地运行测试软件。包括:Apache JMeter 、LoadRunner、NeoLoad等

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!