React 组件测试【React Testing Library】

ops/2025/3/13 12:02:05/

文章目录

    • 前言
    • 安装和配置
    • 基本用法
    • 运行测试代码
    • 使用自定义钩子
    • 测试用例截图

前言

  • Testing Library 是一个以用户为中心前端测试工具集,关注用户行为和交互,而不是组件的内部实现细节。这意味着测试更加关注组件的行为,而不是具体的实现方式
  • 基于 DOM Testing Library,为 React、Angular、Vue 等框架提供了特定的封装,如 React Testing LibraryVue Testing LibraryAngular Testing Library
  • @testing-library/user-event 提供通用的用户事件模拟功能,不依赖于特定框架;@testing-library/jest-dom 为 Jest 测试框架提供自定义断言器

React Testing Library 是一个用于测试 React 组件的轻量级库,它提供了一组工具来模拟用户交互、检查组件的状态和属性,并与 Jest 等测试框架配合使用。它的设计理念是尽可能地模拟用户行为,使测试更加贴近真实场景。

安装和配置

安装
使用 npm 或 yarn 安装 React Testing Library 和 babel 相关依赖:

npm install --save-dev jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript babel-jest jest-environment-jsdom @testing-library/dom @testing-library/jest-dom @testing-library/react
# 或者
yarn add --dev jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript babel-jest jest-environment-jsdom @testing-library/dom @testing-library/jest-dom @testing-library/react

配置 Babel
在项目根目录下创建 .babelrc 文件

{"presets": ["@babel/preset-env","@babel/preset-react","@babel/preset-typescript"]
}

配置 Jest
在项目根目录下修改 package.json 文件中的 scripts 部分:

{"scripts": {"test": "jest"}
}

在项目根目录下创建 jest.config.js 文件:

module.exports = {modulePaths: ["src"],moduleNameMapper: {"\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",},// 入口文件setupFilesAfterEnv: ["<rootDir>/src/setupTests.js"],// 使用babel对jsx文件预处理transform: {"^.+\\.[jt]sx?$": "babel-jest",},
};

src 目录下创建 setupTests.js 文件:

import "@testing-library/jest-dom";

基本用法

组件编写

src目录下创建 Hello.tsx 文件:

import React, { useState } from "react";export const Hello = () => {let [count, setCount] = useState(0);return (<div className="hello"><div id="hello">{count}</div><button onClick={() => setCount(count + 1)}> count+1 </button></div>);
};

测试用例编写
src目录下创建 Hello.test.jsx 文件:

  • render:渲染组件并返回一个包含 DOM 和事件的对象。
  • screen.getByText:查找包含特定文本的元素。
  • screen.getByTestId:查找具有特定 data-testid 属性的元素。
  • fireEvent.click:模拟点击事件。
  • fireEvent.change:模拟表单元素的值变化。
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { Hello } from "./Hello";test("renders learn react link", async () => {const { container } = render(<Hello />);// DOM 查找expect(container.querySelector("#hello")).toBeTruthy();expect(container.getElementsByClassName("hello")).toHaveLength(1);// 获取元素值expect(container.querySelector("#hello").textContent).toBe("0");// 事件触发  状态管理await fireEvent.click(screen.getByText("count+1"));// 获取状态变更expect(container.querySelector("#hello").textContent).toBe("1");
});

运行测试代码

打开 cmd,输入命令:

yarn test

使用自定义钩子

React Testing Library 支持自定义钩子,用来测试自定义钩子,创建src/useCounter.js

import React, { useState } from "react";export const useCounter = (initialCount = 0) => {const [count, setCount] = useState(initialCount);const increment = () => {setCount((prevCount) => prevCount + 1);};return { count, increment };
};

创建src/useCounter.test.js

import { renderHook ,act} from "@testing-library/react";
import { useCounter } from "./useCounter";describe("useCounter", () => {// 测试初始值test("测试初始值", () => {const { result } = renderHook(() => useCounter(5));expect(result.current.count).toBe(5);});// 测试 increment 功能test(" 测试 increment 功能", () => {const { result } = renderHook(() => useCounter(0));act(() => {result.current.increment();});expect(result.current.count).toBe(1);});
});

测试用例截图

在这里插入图片描述


http://www.ppmy.cn/ops/165410.html

相关文章

设备物联网无线通信,ESP32-C3芯片模组方案,智能化联动控制

在这个数字化与智能化交相辉映的时代&#xff0c;科技早已不是束之高阁的抽象概念&#xff0c;而是如同空气一般&#xff0c;悄无声息却又实实在在地渗透进我们生活的每一处角落。 智能设备通过互联互通&#xff0c;构建起一个高效便捷的智能化交互生态系统&#xff0c;让人们…

19874并查集

19874并查集 ⭐️难度&#xff1a;中等 &#x1f31f;考点&#xff1a;并查集、数据结构 &#x1f4d6; &#x1f4da; import java.util.*;public class Main {static int N 100010;static int[] a new int[N];static int[] p new int[N];static int n;static int m;st…

TensorFLow深度学习实战(11)——风格迁移详解

TensorFLow深度学习实战&#xff08;11&#xff09;——风格迁移详解 0. 前言1. 风格迁移原理1.1 内容损失1.2 风格损失 2. 模型分析3. 使用 TensorFlow 实现神经风格迁移小结系列链接 0. 前言 风格迁移是用于训练神经网络创作艺术作品的深度学习技术&#xff0c;同时也是一种…

Jetpack Navigation 实战:Fragment 和 Activity 的交互与导航

在 Android 开发中&#xff0c;使用 Jetpack Navigation 组件可以方便地管理 Fragment 和 Activity 之间的导航。以下是如何使用 Jetpack Navigation 实现 Fragment 之间、Activity 之间以及 Activity 与 Fragment 之间跳转的实战示例。 1. 添加依赖 首先&#xff0c;在 build.…

Deep research深度研究:ChatGPT/ Gemini/ Perplexity/ Grok哪家最强?(实测对比分析)

目前推出深度研究和深度检索的AI大模型有四家&#xff1a; OpenAI和Gemini 的deep research&#xff0c;以及Perplexity 和Grok的deep search&#xff0c;都能生成带参考文献引用的主题报告。 致力于“几分钟之内生成一份完整的主题调研报告&#xff0c;解决人力几小时甚至几天…

嵌入式软件测试的东方智慧:WinAMS工具的技术哲学与实践启示——一名汽车电子工程师的七年工具演进观察

引言&#xff1a;在丰田精益生产线上诞生的测试哲学 2017年参与某日系车企的ECU&#xff08;电子控制单元&#xff09;联合开发时&#xff0c;我第一次在名古屋工厂见到产线旁部署的WinAMS测试站。不同于欧美工具强调的“全流程覆盖”&#xff0c;这个诞生于日本制造业精益文化…

看不见的“健康杀手”来袭,微塑料竟威胁人体与植物光合作用

文末结尾有神器分享&#xff01; 塑料相信大家都不陌生&#xff0c;生活的方方面面都在使用&#xff0c;而微塑料是指直径小于5毫米的塑料颗粒或塑料碎片。它们通常来源于两种主要途径&#xff1a;第一种是较大塑料物品的降解&#xff0c;例如塑料瓶、袋子和包装材料&#xff0…

「 DelegateUI 」Ant-d 风格的 Qt Qml UI 套件

写在前面&#xff1a;关于为什么要写一套新的UI框架 一方面&#xff0c;Qt Qml 生态中缺乏一套既遵循现代设计规范(自带的功能少且丑,懂得都懂)&#xff0c;又能深度整合 Qt 生态的开源组件库。 另一方面&#xff0c;Qt Qml 中也有一些其他方案&#xff0c;例如 FluentUI Qml…