当前位置: 首页 > news >正文

Jest进阶知识:测试快照 - 确保组件渲染输出正确

在 React 应用开发中,确保组件的渲染输出正确是一项重要的测试任务。快照测试是一种有效的方法,可以帮助开发者捕捉并验证组件的渲染输出,确保其在不同的情况下保持一致。

什么是快照测试?

快照测试的基本思想是:

  1. 首次运行测试:将组件的渲染输出记录到一个快照文件中。
  2. 后续运行测试:将组件的渲染输出与快照文件进行对比,确保两者一致。

快照测试可以有效地捕获意外的更改,确保组件的渲染输出不会因为代码的改动而发生不必要的变化。

快速上手

假设我们有一个简单的组件 App,它显示一个待办事项列表,并允许用户添加新的事项:

import { useState } from "react";function App() {const [items, setItems] = useState(["苹果", "香蕉", "西瓜"]);const [value, setValue] = useState("");const lis = items.map((it, idx) => <li key={idx}>{it}</li>);function addItem() {if (items) {const newItems = [...items];newItems.push(value);setItems(newItems);setValue("");}}return (<div className="App"><inputtype="text"value={value}onChange={(e) => setValue(e.target.value)}/><button onClick={addItem}>添加</button><ul>{lis}</ul></div>);
}export default App;

接下来,我们编写测试代码来生成快照:

import { render } from '@testing-library/react';
import App from './App';test('renders learn react link', () => {const { baseElement } = render(<App />);expect(baseElement).toMatchSnapshot();
});

首先从 render 方法中解构出 baseElement(注意 render 方法来源于 testing library)

接下来调用了 toMatchSnapshot(这个方法是 jest 提供的方法)来生成快照。

image-20230511092759962

通过执行结果也可以看到,生成了一张快照,并且在我们的项目目录中(和你的测试文件是同级的),生成了一个名为 _snapshots_ 的目录,里面就是一张测试快照,测试快照的本质就是渲染出来的 DOM 的结构的字符串序列。

// Jest Snapshot v1, https://goo.gl/fbAQLPexports[`renders learn react link 1`] = `
<body><div><divclass="App"><inputtype="text"value=""/><button>添加</button><ul><li>苹果</li><li>香蕉</li><li>西瓜</li></ul></div></div>
</body>
`;

之后在下一次测试的时候,针对这个组件测试,就会将组件渲染出来的 DOM 结构的序列和之前的快照进行一个比对,看是否一致,如果和之前的快照是一致的,那么测试就通过,如果不一致(这一次渲染新增了DOM节点或者少了DOM 节点),那么就说明这一次渲染和之前的渲染不一致的,测试不通过。

如下图所示:

image-20230511093235552
快照测试的注意事项
  1. 快照本身并不验证渲染逻辑是否正确:快照测试的主要目的是防止意外的更改。如果测试失败,需要检查是否有不期望的更改。
  2. 更新快照:如果确定渲染逻辑没有问题,但结构确实需要更改,可以使用 jest --updateSnapshot 命令更新快照。
避免大快照

在复杂的组件中,直接对整个组件进行快照会导致快照文件非常大。为了生成更小的快照,可以只针对特定的部分进行快照:

import { render, screen } from '@testing-library/react';
import App from './App';test('renders learn react link', () => {render(<App />);const content = screen.getByTestId('list');expect(content).toMatchSnapshot();
});

在这个例子中,我们只针对 TestUI 组件生成快照。

扩展场景
  1. 快照测试不仅适用于组件的 UI 测试,还可以用于其他场景。例如,对于 HTTP 请求的返回结果进行快照测试:
// getUserById.ts
const getUserById = async (id: string) => {return request.get('user', {params: { id }});
};// getUserById.test.ts
describe('getUserById', () => {it('可以获取 userId == 1 的用户', async () => {const result = await getUserById('1');expect(result).toMatchSnapshot();});
});
  1. 很多人喜欢把快照测试等同于组件的 UI 测试,但是快照有些时候在其他的某一些场景下使用也非常方便:
// getUserById.ts
const getUserById = async (id: string) => {return request.get('user', {params: { id }})
}// getUserById.test.ts
describe('getUserById', () => {it('可以获取 userId == 1 的用户', async () => {const result = await getUserById('1')expect(result).toEqual({// 非常巨大的一个 JSON 返回...})})
});

比如在上面的示例中,http 请求返回的结果是比较大的,这个时候就会有一些冗余的代码,在写 expect 断言的时候就会比较麻烦。

这个时候你就可以使用快照:

// getUserById.ts
const getUserById = async (id: string) => {return request.get('user', {params: { id }})
}// getUserById.test.ts
describe('getUserById', () => {it('可以获取 userId == 1 的用户', async () => {const result = await getUserById('1')expect(result).toMatchSnapshot();})
});
总结

快照测试是一种简单有效的工具,可以帮助开发者确保组件的渲染输出在不同情况下保持一致。通过合理使用快照测试,可以提高代码的可靠性和可维护性。需要注意的是:

  • 生成小快照:只取重要的部分来生成快照,确保快照是可读的。
  • 合理使用快照:快照测试不仅限于组件测试,可以应用于任何可序列化的内容。

通过遵循这些最佳实践,可以避免快照测试中的“假错误”,确保测试的有效性。


http://www.mrgr.cn/news/66457.html

相关文章:

  • 人工智能学习--ANN模型、SVR模型
  • 从无到有:模拟 STL 栈和队列的抽象构建艺术
  • MySQL 8.0的Public Key Retrival问题解决
  • 【力扣 + 牛客 | SQL题 | 每日5题】牛客SQL热题216,217,223
  • 33.安卓逆向-壳-查壳
  • [每日一练]使用nunique函数查找唯一值
  • 2024年专业的10款数据恢复工具你都用过哪些?
  • 鸿蒙应用开发:下载功能
  • 【020】基于51单片机病房呼叫系统
  • 105. UE5 GAS RPG 搭建主菜单
  • Qt 环境实现视频和音频播放
  • 负载均衡与容错的基本原则
  • C#-类:索引器
  • 【xml转JSON】
  • windows_worm
  • 信号与噪声分析——第三节:随机过程的统计特征
  • 对于IIC的理解
  • 蓝桥杯2021年题解(IP补充)
  • QStackedWidget使用实例
  • Java 基于SpringBoot+Vue 的公交智能化系统,附源码、文档
  • 【C++篇】在秩序与混沌的交响乐中: STL之map容器的哲学探寻
  • 一些常规IP核功能
  • HOT100_最大子数组和
  • 一款功能强大的开源文档管理系统,将物理文档转换为可搜索的在线档案,实现无纸化办公工具(带私活源码)
  • Spring Data Redis的基本使用
  • 【大模型】深度解析:智能体如何突破 RAG 的三大技术瓶颈