在 React 应用开辟中,确保组件的渲染输出精确是一项紧张的测试任务。快照测试是一种有用的方法,可以资助开辟者捕获并验证组件的渲染输出,确保其在差别的环境下保持划一。
什么是快照测试?
快照测试的根本头脑是:
- 初次运行测试:将组件的渲染输出记载到一个快照文件中。
- 后续运行测试:将组件的渲染输出与快照文件举行对比,确保两者划一。
快照测试可以有用地捕获不测的更改,确保组件的渲染输出不会由于代码的改动而发生不须要的变革。
快速上手
假设我们有一个简单的组件 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">
- <input
- type="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 提供的方法)来天生快照。
通过实行效果也可以看到,天生了一张快照,而且在我们的项目目次中(和你的测试文件是同级的),天生了一个名为 _snapshots_ 的目次,内里就是一张测试快照,测试快照的本质就是渲染出来的 DOM 的布局的字符串序列。- // Jest Snapshot v1, https://goo.gl/fbAQLP
- exports[`renders learn react link 1`] = `
- <body>
- <div>
- <div
- class="App"
- >
- <input
- type="text"
- value=""
- />
- <button>
- 添加
- </button>
- <ul>
- <li>
- 苹果
- </li>
- <li>
- 香蕉
- </li>
- <li>
- 西瓜
- </li>
- </ul>
- </div>
- </div>
- </body>
- `;
复制代码 之后在下一次测试的时间,针对这个组件测试,就会将组件渲染出来的 DOM 布局的序列和之前的快照举行一个比对,看是否划一,如果和之前的快照是划一的,那么测试就通过,如果差别等(这一次渲染新增了DOM节点大概少了DOM 节点),那么就阐明这一次渲染和之前的渲染差别等的,测试不通过。
如下图所示:
快照测试的注意事项
- 快照自己并不验证渲染逻辑是否精确:快照测试的紧张目的是防止不测的更改。如果测试失败,必要查抄是否有不盼望的更改。
- 更新快照:如果确定渲染逻辑没有标题,但布局确实必要更改,可以使用 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 组件天生快照。
扩展场景
- 快照测试不但实用于组件的 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();
- });
- });
复制代码
- 许多人喜欢把快照测试等同于组件的 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();
- })
- });
复制代码 总结
快照测试是一种简单有用的工具,可以资助开辟者确保组件的渲染输出在差别环境下保持划一。通过公道使用快照测试,可以进步代码的可靠性和可维护性。必要注意的是:
- 天生小快照:只取紧张的部门来天生快照,确保快照是可读的。
- 公道使用快照:快照测试不但限于组件测试,可以应用于任何可序列化的内容。
通过遵照这些最佳实践,可以克制快照测试中的“假错误”,确保测试的有用性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |