Vitest --changed 漏掉非 ASCII 文件,退出 0 也可能没跑测试
Git 给特殊文件名加引号后,旧 Vitest 把输出当成真实路径。升级需覆盖原带特殊字符的文件,不能只确认退出码。
vitest run --changed 显示 No affected test files found,退出码还是 0;完整运行却能找到失败断言。如果变化文件名含 é、双引号、反斜杠或制表符,检查 Git 输出的路径有没有被引号包住。
这条问题在 Vitest 5.0.4 和 4.1.11 中出现。旧逻辑读取 git diff --name-only 等命令的文本,按换行拆分并直接当路径;Git 为特殊文件名生成的引号和转义序列并不是磁盘名称,最终自然匹配不到测试。
“没有变化”与“路径没被识别”要分开
例如默认 core.quotePath=true 时,Git 可能把 é.test.js 显示为 "\303\251.test.js"。引号中的反斜杠和数字表示编码后的输出,不应直接拿来拼绝对文件路径。
先保存实际测试命令、比较基准、Git 状态和变化文件名。--changed 使用不同基准、测试从未导入那个源文件、测试 include 排除了文件,也会得到空结果;只有特殊路径在完整运行中可找到,而变化筛选丢失时,才吻合这条分支。
把 core.quotePath 全局设为 false 不是完整修复。它会改变非 ASCII 的显示,但双引号、反斜杠和换行等名称仍需转义。也不宜为了测试工具临时批量改名,特别是在大小写敏感性或外部路径契约已经固定的仓库。
5.0.5 已按 NUL 分隔读取文件列表
Vitest 5.0.5 的正式 Git provider 对相关命令加入 -z,并按 \0 拆分,避免把显示用引号当成路径。项目兼容时采用包含修正的正式版,并确认 CI、工作区和编辑器实际使用同一版本。
短期不能更新时,让关键 CI 任务运行完整测试集,或通过经过正确参数传递的既有入口显式运行受影响文件。完整运行会增加时间和资源,需使用原测试隔离条件;不能把“没有筛选到任何文件”当作质量门槛。
不要用 --passWithNoTests 一类选项掩盖发现问题。故障本身就可能以成功退出结束,继续放宽空运行只会减少可观察信号。
让原文件进入测试结果
保留一个带原特殊字符名称、含已知失败断言的受控检查,确认 --changed 列出并运行该文件,返回失败;恢复正确断言后再确认通过。分别检查已暂存、未暂存及项目使用的比较基准,不能只覆盖新建的普通英文文件。
完整测试结果与变化筛选结果应能解释同一处变更。若后续仍漏跑,继续核对依赖图、被删除文件与 setup 的加载方式,那些是独立的筛选路径,不能由一次路径解码修复全部保证。回退时恢复工具锁文件和 CI 命令,不改变业务文件名来迁就旧解析。


