React团队是如何测试并发特性的
大家好,团特性我卡颂。队何
React18进入大家视野已经有一段时间了,测试不知道各位有没有尝试「并发特性」呢?团特性

当启用「并发特性」后,React会从「同步更新」变为「异步、队何带优先级、测试可中断的团特性更新」。
这也为编写单元测试带来了一些难度。队何
本文来聊聊React团队如何测试并发特性。测试
遇到的团特性困境
主要有两个问题需要面对。
1. 如何表达渲染结果?队何
React可以对接不同宿主环境的渲染器,大家最熟悉的测试渲染器想必是ReactDOM,用于对接「浏览器」与「Node环境」(SSR)。团特性
对于一些场景,队何可以用ReactDOM的测试输出结果做测试。
比如,下面是使用ReactDOM的输出结果测试「无状态组件的渲染结果是否符合预期」(测试框架是jest):
it(should render stateless component, () => {
const el = document.createElement(div);
ReactDOM.render(
expect(el.textContent).toBe(A);
});这里有个不方便的地方 —— 这个用例依赖浏览器环境与DOM API(比如用到document.createElement)。
对于测试「React内部运行机制」这样的场景,掺杂了宿主环境相关信息显然会让测试用例编写起来更繁琐。
2. 如何测试并发环境?
如果将上文的用例中ReactDOM.render改为ReactDOM.createRoot,亿华云那么用例就会失败:
// 之前
ReactDOM.render(
expect(el.textContent).toBe(A);
// 之后
ReactDOM.createRoot(el).render(
这是因为在新的架构下,很多「同步更新」变成了「并发更新」,当render执行后,页面还没完成渲染。
要让上述用例成功,最简单的修改方式是:
ReactDOM.createRoot(el).render(
setTimeout(() => {
// 异步获取结果
expect(el.textContent).toBe(A);
})如何优雅的应对这种变化?
React的应对策略
接下来我们来看React团队的应对方式。
首先来看第一个问题 —— 如何表达渲染结果?
既然ReactDOM渲染器对应浏览器、Node环境,ReactNative渲染器对应Native环境。
那能不能为测试「内部运行流程」专门开发一个渲染器呢?
答案是肯定的。
这个渲染器叫React-Noop-Renderer。
简单的说,这个渲染器会渲染出纯JS对象。
实现一个渲染器
React内部有个叫Reconciler的包,他会引用一些「操作宿主环境」的API。
比如如下方法用于「向容器中插入节点」:
function appendChildToContainer(child, container) {
// 具体实现
}对于浏览器环境(ReactDOM),使用appendChild方法实现即可:
function appendChildToContainer(child, container) {
// 使用appendChild方法
container.appendChild(child);
}打包工具(rollup)将Reconciler包与上述这类「针对浏览器环境的API」打包起来,就是ReactDOM包。
在React-Noop-Renderer中,WordPress模板与ReactDOM中的DOM节点对标的是如下数据结构:
const instance = {
id: instanceCounter++,
type: type,
children: [],
parent: -1,
props
};注意其中的children字段,用于保存子节点。
所以appendChildToContainer方法在React-Noop-Renderer中可以实现的很简单:
function appendChildToContainer(child, container) {
const index = container.children.indexOf(child);
if (index !== -1) {
container.children.splice(index, 1);
}
container.children.push(child);
};打包工具将Reconciler包与上述这类「针对React-Noop的API」打包起来,就是React-Noop-Renderer包。
基于React-Noop-Renderer,可以完全脱离正常的宿主环境,测试Reconciler内部的逻辑。
接下来来看第二个问题。
如何测试并发环境?
「并发特性」再复杂,说到底也只是「各种异步执行代码的策略」,最终执行策略的API不外乎setTimeout、setInterval、Promise等。
在jest中,可以模拟这些异步API,控制他们的执行时机。
比如上面的异步代码,在React中的测试用例会这么写:
// 测试用例修改后:
await act(() => {
ReactDOM.createRoot(el).render(
})
expect(el.textContent).toBe(A);act方法来自jest-react包,云服务器提供商他的内部会执行jest.runOnlyPendingTimers方法,让所有等待中的计时器触发回调。
比如如下代码:
setTimeout(() => {
console.log(执行)
}, 9999999)执行jest.runOnlyPendingTimers后会立刻打印「执行」。
通过这种方式,人为控制React并发更新的速度,同时对框架代码0侵入。
除此之外,用于驱动并发更新的Scheduler(调度器)模块,本身也有一个针对测试的版本。
在这个版本中,开发者可以手动控制Scheduler的输入、输出。
比如,我想测试组件卸载时useEffect回调的执行顺序。
如下面代码所示,其中Parent为挂载的「被测试组件」:
function Parent() {
useEffect(() => {
return () => Scheduler.unstable_yieldValue(Unmount parent);
});
return
}
function Child() {
useEffect(() => {
return () => Scheduler.unstable_yieldValue(Unmount child);
});
return Child;
}
await act(async () => {
root.render(
根据yieldValue的插入顺序是否符合预期,就能确定useEffect的逻辑是否符合预期:
expect(Scheduler).toHaveYielded([Unmount parent, Unmount child]);总结
React中测试用例的编写策略为:
可以用ReactDOM测的用例,一般结合ReactDOM与ReactTestUtils(浏览器环境的辅助方法)完成
需要把控中间过程的用例,使用Scheduler的测试包,用Scheduler.unstable_yieldValue记录过程信息
脱离宿主环境,单独测试React内部运行流程的,使用React-Noop-Renderer
测试并发下的场景,需要结合上述工具与jest-react一起使用
如果想深入学习下React中与测试相关的技巧,可以看下司徒正美老师的作品anu[1]。
这是个类React框架,但能跑通800+的React用例。里面实现了ReactTestUtils、React-Noop-Renderer的简化版。
相关文章
利用灯泡测试教程,轻松了解电脑的工作原理(通过灯泡测试教程,揭秘电脑内部的神秘世界)
摘要:在数字时代的今天,电脑已经成为我们生活中不可或缺的一部分。然而,对于普通用户来说,电脑的内部结构和工作原理可能依然充满了神秘感。本文将介绍一种简单且有趣的方法——灯泡测试教程,通过...2025-11-052016年电脑行业的发展与趋势(洞悉2016年电脑行业的变化,把握发展机遇)
摘要:随着科技的迅速发展,电脑行业一直是其中的佼佼者。2016年,作为信息技术领域的重要组成部分,电脑行业经历了许多变革和创新。本文将通过分析2016年电脑行业的发展与趋势,探讨这一年行...2025-11-05L58E6800AUDS带来怎样的视觉体验?(探索UDS技术在L58E6800A电视上的应用与优势)
摘要:如今,电视作为人们家庭娱乐生活中不可或缺的一部分,对于画质和视觉体验的要求越来越高。而L58E6800AUDS技术的应用,为用户提供了更加逼真细腻的画面效果,让观影体验更上一层楼。...2025-11-05艾优尼iuniN1的综合评价与优势分析(探索艾优尼iuniN1的功能、性能和用户体验)
摘要:随着智能科技的不断发展,手机已经成为人们生活中不可或缺的一部分。艾优尼iuniN1作为一款备受关注的智能手机,它凭借其独特的设计、出色的性能和卓越的用户体验,在市场上受到了广泛的赞...2025-11-05如何自动生成Word文档目录的序号(简便有效的方法让你省时省力)
摘要:在撰写长篇文档时,我们常常需要添加目录以方便读者阅读。然而,手动为目录添加序号是一项繁琐而耗时的任务。本文将介绍一种简便有效的方法,帮助你轻松自动生成Word文档目录的序号,让你节...2025-11-05宏图三胞电脑的性能与可靠性分析(一起来了解宏图三胞电脑的优势和特点)
摘要:近年来,电脑技术的迅猛发展使我们的工作和生活变得更加便捷高效。在众多电脑品牌中,宏图三胞电脑以其优秀的性能和出色的可靠性备受消费者青睐。本文将对宏图三胞电脑进行全面分析,深入探讨其...2025-11-05

最新评论