nodejs / nodejs/node

test_runner: change-aware test selection

未关闭
#66,006 2 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

主要语言
JavaScript
星标
122k
派生
37.4k
平均合并
4 天 3 小时
30 天内合并 PR
272

描述

What is the problem this feature will solve?

node --test always runs every test file. There is no way to run only the tests affected by a change.

--watch does this, but only while it stays running. CI, a pre-commit hook, or a branch diff all start cold and run everything.

Jest (--onlyChanged) and Vitest (--changed) both do this.

What is the feature you are proposing to solve the problem?

Run only the test files whose module graph reaches a given set of files.

$ node --test --related=src/util.ts               # tests that depend on a file
$ git diff --name-only | node --test --related=-  # tests affected by a change

Graph-aware, not path-based: a test that imports a module that imports the changed file is selected. Conservative by default, so anything the graph cannot see has to run, and a change to package.json or a lockfile disables filtering entirely.

Paths rather than a --changed=<rev> flag, because that would mean core shelling out to git. There is no VCS dependency anywhere in lib/ today and I don't think this justifies introducing one. --changed can be layered on later if the team wants it.

Things to figure out
  • CJS. Static imports can be extracted from an ES module without executing it. There is no equivalent for require(), since the bundled lexer reports exports rather than requires. CJS files would be opaque: any test reaching one always runs. Correct, but a CJS-heavy project gets little out of this.
  • Invisible dependencies. A test that reads a fixture with fs, or uses dynamic import(), cannot be selected statically. Those have to resolve to "run it".

Under-selection is the failure mode that matters. Silently skipping a test the change broke is worse than not having the feature.

What alternatives have you considered?

Userland: a wrapper computing the list and passing it to run({ files }). Every such tool has to reimplement module resolution, and gets TypeScript, subpath imports and node_modules boundaries subtly wrong. The resolver is already in core.

--test-rerun-failures covers rerunning what failed, not running what a change could break.

cc @nodejs/test_runner

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

node --test 入口点、现有的 --watch 实现和 run({ files }) 开始;然后跟踪测试运行器使用的 resolver。完成标准是通过静态模块依赖选择测试,同时对具有不透明依赖或全局包变更的测试采取保守运行策略,并覆盖所述的 CJS 和不可见依赖情况。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, node.js
领域
cli, testing
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
活跃
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。