AVA:Node.js 测试跑得快,还看得清

写 Node.js 项目,测试这块总有人纠结用什么框架。Jest 生态大,Mocha 老牌稳,但有个叫 AVA 的工具,2 万多 Star,一直在圈子里有口皆碑。它主打的就是两件事:快,以及报错信息看得懂。

正文顶部截图

它到底解决了什么问题

做测试最烦的两件事:一是测试跑得慢,改一行代码等半天;二是报错信息一堆堆栈,看不出到底哪里挂了。AVA 把这两个痛点都处理了。

先说速度。AVA 默认并发执行测试文件,不是像有些框架那样一个一个排队跑。你有 10 个测试文件,它就同时跑 10 个。单个文件里的测试用例也是并发的,除非你显式声明依赖关系。这个设计在项目大了以后差距很明显,几百个测试用例从分钟级压到秒级是常事。

再说报错。AVA 有个叫 Magic Assert 的功能,断言失败的时候,它不会甩一堆对象属性给你看,而是直接显示实际值和期望值的 diff。如果是对象或数组,只展示差异部分;如果是字符串,高亮标出多了或少了哪些字符。这个细节看着小,实际调试的时候省了不少时间。

用起来什么感觉

安装很简单,一条命令搞定:

npm init ava

它会自动帮你配好 package.json 里的依赖和 test 脚本。写测试文件也直接,ES 模块语法,import 进来就能用:

import test from 'ava';

test('foo', t => {
    t.pass();
});

test('bar', async t => {
    const bar = Promise.resolve('bar');
    t.is(await bar, 'bar');
});

跑测试就 npm test,想实时监听文件变化就加 --watch 参数。整个流程没什么学习成本,会写 JavaScript 就能上手。

README区域截图

几个值得注意的设计

AVA 强制每个测试用例是独立的,不允许测试之间共享状态。这个约束一开始可能觉得麻烦,但写多了会发现它帮你避免了很多"测试之间互相影响"的坑。某个测试改了个全局变量,另一个测试就挂了,这种事在 AVA 里基本不会发生。

它还支持 Promise、async/await、Observable 这些异步模式。现在写 Node.js 很少有纯同步的代码了,测试框架对异步的支持好不好直接决定了能不能用。AVA 这块做得比较早,也做得比较扎实。

另外,每个测试文件跑在独立的 worker 线程里,不是共享同一个进程。这意味着文件级别的隔离是天然的,不需要额外配置。对于需要测试数据库操作、文件读写这类有副作用的场景,这个隔离很有用。

CI 环境下的表现

AVA 能自动检测 CI 环境,把测试文件分摊到多个构建任务上并行跑。比如你有 100 个测试文件,CI 开了 4 个 worker,AVA 会自动分配,每个 worker 跑 25 个左右,不用你手动拆分。支持的 CI 平台也挺全,GitHub Actions、Travis、CircleCI 这些主流的都能识别。

和 Jest 比怎么样

这是被问得最多的问题。Jest 功能更全,内置了 mock、snapshot、覆盖率这些,开箱即用。AVA 更专注,它就管测试执行和断言,mock 和覆盖率靠社区插件。选哪个取决于你的需求:如果你想要一个大而全的方案,Jest 合适;如果你更看重执行速度和报错清晰度,而且愿意自己组合工具链,AVA 是更好的选择。

AVA 对 ES 模块的支持也比较积极,很早就原生支持了 import/export 语法,不用额外配置 Babel。这点在现在 ESM 逐渐成为主流的背景下,是个加分项。

TypeScript 支持

项目自带 TypeScript 类型定义,写测试的时候有完整的类型提示。如果要直接用 TypeScript 写测试文件,有 @ava/typescript 这个官方包可以配合。配置不算复杂,但比 Jest 多一步,这是事实。

说点实际的

AVA 这工具适合什么人?如果你的 Node.js 项目测试用例比较多,跑一次要等很久,可以试试 AVA,并发执行的优势在这种场景下最明显。如果你经常被 Jest 那种冗长的报错信息搞得很烦,AVA 的 Magic Assert 会让你觉得清爽。

不太适合的场景:项目很小,测试就十几个,那用啥都差不多,没必要折腾。还有就是团队已经在用 Jest 且没有痛点,换框架的迁移成本不值得。

总的来说,AVA 是一个把"测试执行"这件事做到位了的工具。不贪多,但做的部分确实做得好。

st 且没有痛点,换框架的迁移成本不值得。

总的来说,AVA 是一个把"测试执行"这件事做到位了的工具。不贪多,但做的部分确实做得好。

更多推荐