React 测试笔记 01 - 基础 UI 类
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React 测试笔记 01 - 基础 UI 类相关的知识,希望对你有一定的参考价值。
React 测试笔记 01 - 基础 UI 类
依稀记得去年找 Hooks 开发的时候还没这么多资料,感觉大半年过去之后科技立马跟上,@testing-library/react 已经成了 CRA 的内置包了……
别卷了,卷不动了.jpg
不过 React Testing Library 结合 jest-dom 确实提供了很多非常方便的测试函数,之后的需求也是项目需要更加正式一点,除了开发之外还要包含测试,那就……学起来吧。
基础 UI 测试
在测试文件中实现以下内容:
import fireEvent, render, screen from "@testing-library/react";
test("basic test", () =>
render(<Component />);
const btn = screen.getByRole("button", name: /submit/i );
);
就能获得一个可以用来测试的 button
元素。
除了 getByRole
之外,React Testing Library 还提供了其他的 query 方法,包括 getByLabelText
, getByPlaceholderText
等,具体内容可以看 About Queries 中列举的所有 queries。
getByRole
中接受的是 ARIA roles,这个定义不是出自 React Testing Library,具体的 roles 也可以在 MDN ARIA 文档 中找到。
第二个参数 name
是 W3C 定义的 Accessible Name,具体文档在 Accessible Name and Description Computation 1.1,比较通俗一点的理解就是 非自闭元素中的内容。以 const btn = screen.getByRole("button", name: /submit/i );
为例,所渲染的 React Component 中必须要包含一个 <button>Submit</button>
,否则就会报错:
注 1*: 这样对于 语义化(semantic) 的要求就更高了,尤其是在很多内容可能需要动态渲染的情况下,添加合适的 altText
之类 accessibility 和 usability 的要求会提升很多。
注 2*:一旦遇到报错信息,Test 会终止继续运行测试,即,不会执行剩下 test('', () => )
中的代码,如:
其他 test()
和 test Suite 不受影响。
通过返回 Element 中提供的函数,如:
-
fireEvent
这是一个交互函数,用法有两种:
// 传入两个参数 fireEvent(node: htmlElement, event: Event) // 或者 fireEvent.click(node);
第一种适合比较复杂的业务场景,或是有很多功能相同的 onclick 事件:
const myEvent = createEvent.click(node, button: 2 ); fireEvent(node, myEvent);
第二种比较适合只是需要触发某个点击事件,如:
expect(btn).toBeEnabled(); fireEvent.click(btn); expect(btn).toBeDisabled();
-
toBeEnabled()
&toBeDisabled()
用法上面有所展示
-
toHaveStyle()
可以用来测试 CSS,如:
expect(colorButton).toHaveStyle( backgroundColor: "blue" );
-
…其他
这部分的功能由 jest-dom 提供,具体文档在 Custom matchers 中有列举。掐指一算有这么三四十个,完整的列一遍不太现实,之后边用边查边记录吧。
React Testing Library 结合 jest-dom 这样就可以完成比较基础的 UI 和功能测试。
一点测试代码
目前在写的简单测试:
import fireEvent, render, screen from "@testing-library/react";
import Page from "./index";
const initialization = () =>
render(<Page />);
return
btn: screen.getByRole("button"),
check: screen.getByRole("checkbox"),
;
;
describe("Test click btn to enable/disable checkbox", () =>
test("test checkbox check func", () =>
const btn, check = initialization();
expect(check).not.toBeChecked();
fireEvent.click(btn);
expect(check).toBeChecked();
);
);
因为在做 TDD 的尝试,所以就是一片红:
Page 实现的代码为:
import React from "react";
const Page = () =>
return (
<>
<button>Submit</button>
</>
);
;
export default Page;
因此 btn 是能够找到的,但是找不到 checkbox.
这个报错信息是我使用的另一个插件(需要付费我就不安利了)生成的,如果用 jest --watchAll
的话显示的报错信息也是一样。
TDD 的需求在于,先写完测试,根据测试去实现功能,这样不会 diverge 到其他自己脑袋一拍的需求(因为要写更多测试所以根本懒得做吧……)。
测试的一些 update
懒得继续修改了,所以这里更新一下修正的测试代码:
import fireEvent, render, screen from "@testing-library/react";
import Page from "./index";
const initialization = () =>
render(<Page />);
return
btn: screen.getByRole("button"),
check: screen.getByRole("checkbox"),
;
;
describe("Checkbox & Btn interaction", () =>
test("click btn enable/disable checkbox", () =>
const btn, check = initialization();
expect(check).toBeEnabled();
fireEvent.click(btn);
expect(check).toBeDisabled();
fireEvent.click(btn);
expect(check).toBeEnabled();
);
);
这样才实现点击 btn 之后 enable/disable checkbox 的功能。
一些之后再看的需求
-
async/await 异步测试
React Testing Library 有包含,之后再看
mock API 这种事情的确就是比较麻烦……
-
CSS Module mock
-
⚠️ experimental
-
Linting
以上是关于React 测试笔记 01 - 基础 UI 类的主要内容,如果未能解决你的问题,请参考以下文章