单元测试核心在“准”:准确覆盖边界、稳定复现路径、隔离不确定性;算法函数应为纯函数,输入输出确定,时间/随机数等依赖需外显传参;用 test.each 和 fixture 覆盖典型与边界场景;单测聚焦单一行为,辅以必要断言;属性测试补充人工用例盲区。

核心算法逻辑的单元测试,关键不在“快”,而在“准”——准确覆盖行为边界、稳定复现逻辑路径、隔离不确定因素。高性能体现在测试本身运行快、维护成本低、反馈及时,而非追求毫秒级提速。
聚焦输入输出,不碰副作用
算法函数应是纯函数:给定相同输入,永远返回相同输出,不读写全局状态、不调用 Date.now()、Math.random()、fetch 或 DOM。这样测试才能可重复、可预测。
- 若函数依赖当前时间,把时间作为参数传入:
sortEvents(events, now = Date.now()),测试时传固定毫秒数 - 若内部调用随机数,改为接收
rand = Math.random参数,测试中传() => 0.5 - 避免在测试里 mock 全局对象(如
Date构造函数),容易污染其他测试;优先改代码,让不确定性外显、可控
用数据驱动覆盖典型与边界场景
算法最易出错的地方是边界:空输入、单元素、极值、重复值、已排序/逆序数组等。用 test.each 统一组织,避免复制粘贴式测试。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 例如二分查找:
test.each([[[], 5, -1], [[1], 1, 0], [[1,3,5], 3, 1], [[2,4,6], 5, -1]]) - 每组数据清晰表达「输入数组、目标值、期望索引」,新增 case 只加一行,不易遗漏
- 对复杂结构(如树、图),提前定义好可读的 fixture 对象,比如
const treeA = { val: 1, left: { val: 2 }, right: null }
分层验证:主逻辑 + 辅助断言
一个 test 块只围绕一个明确行为,但可包含多个相关断言,前提是它们共同支撑同一契约。
- 主断言验证核心输出:
expect(quickSort([3,1,2])).toEqual([1,2,3]) - 辅助断言验证隐含约束(可选):
expect(comparisons).toBeLessThanOrEqual(10)(用于性能敏感算法) - 避免混合验证:不要在一个 test 里既测排序结果,又测内存使用量或日志输出——拆到不同 describe 分组里
必要时引入属性测试补盲区
手动写例题总有盲点。对数学性强、泛化要求高的算法(如加密工具、校验和、序列生成器),用 Fast-Check 自动生成海量随机输入,验证不变式。
- 例如验证「反转两次等于原数组」:
fc.assert(fc.property(fc.array(fc.integer()), arr => deepEqual(reverse(reverse(arr)), arr))) - 它会自动尝试空数组、超长数组、负数、NaN、嵌套数组等组合,比人工枚举更彻底
- 不是替代例题测试,而是补充——先写清楚的用例建立信心,再用属性测试兜底边界










