news 2026/9/9 18:56:15

Deno 如何在 Deno 中运行 node:* 兼容层测试并用 config.jsonc 控制用例集合

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Deno 如何在 Deno 中运行 node:* 兼容层测试并用 config.jsonc 控制用例集合

Deno 如何在 Deno 中运行 node:* 兼容层测试并用 config.jsonc 控制用例集合

【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/deno

Deno 的node:*兼容层有两套容易混淆的测试(doc/testing.md 中专门区分了它们):

  • tests/unit_node/— Deno 自己编写的node:*内置模块单元测试,通过cargo test unit_node::<module>运行;
  • tests/node_compat/— Node.js 自己的测试文件,直接在 Deno 上执行来度量兼容性,运行哪一批用例由tests/node_compat/config.jsonc控制

本文讲的是后者:如何在 Deno 源码仓库中运行 Node.js 官方测试用例,以及如何用config.jsonc增删用例、标记 flaky、按平台跳过或配置期望失败。适用前提是你在 Deno 仓库内做兼容性相关的开发或验证(需要先构建出仓库自带的 deno 二进制)。

准备条件

  1. .github/CONTRIBUTING.md的 "building from source" 一节安装 Rust 工具链及原生编译依赖(编译器、cmake 等),并带子模块克隆仓库(CLAUDE.md 要求使用--recurse-submodules)。
  2. 构建开发版 deno:
cargo build --bin deno

node compat 用例本体是 vendored 的 Node.js 测试套件,位于tests/node_compat/runner/suite/(tests/node_compat/README.md 说明它是denoland/node_test的 git 子模块),--recurse-submodules保证该目录有内容。

运行 node compat 测试

入口是tests/node_compat/mod.rs(README 称之为 "The script entrypoint of node")对应的node_compat测试目标。

运行单个用例

tests/node_compat/mod.rs 源码中的注释给出了标准形式,过滤词用"目录/文件名"(不含test/前缀,可写全名或片段):

# 过滤所有名字里带 test-assert 的用例 cargo test --test node_compat -- test-assert # 调试某个用例:让 deno 停在断点处等待调试器 cargo test --test node_compat -- test-assert --inspect-brk

tests/node_compat/README.md 中写的是简写形式cargo test <name of test file>,等价含义;--inspect-brk之外还支持--inspect-wait(见mod.rsparse_cli_args)。

运行 config.jsonc 里登记的全部用例

doc/testing.md 指出./xhelper 封装了常用测试命令,node compat 对应:

./x test-compat <name>

(运行./x --help可查看该 helper 封装的全部命令。)也可以走 tests/node_compat/runner/deno.json 里定义的testtask:

cd tests/node_compat/runner deno task test <过滤词>

该 task 的实际内容是DENO_TEST_UTIL_DENO_EXE="$(deno eval 'console.log(Deno.execPath())')" cargo test --test node_compat --,即把当前 deno 可执行文件路径传给测试 harness 后再跑cargo test --test node_compat

无过滤器时跑的是什么集合

这是理解config.jsonc作用的关键(mod.rsmain()):

  • 不带过滤器:只运行config.jsonc中登记过的用例;
  • 带过滤器:从完整 vendored 套件里运行所有匹配的用例,即使它没登记在config.jsonc里;
  • --report:不做 config 过滤,跑整个套件,且仅在 CI 环境(CI环境变量存在)下生成报告文件。

测试发现规则(collect_test_files_recursive):递归扫描runner/suite/test/下每个子目录,只收集文件名以test-开头、扩展名为.js/.mjs/.cjs/.ts的文件;以.开头的隐藏文件和fixturescommontoolsIGNORED_TEST_DIRS目录会被跳过。

config.jsonc 字段:如何控制用例集合

tests/node_compat/config.jsonc的格式由 tests/node_compat/schema.json 定义,结构是{"tests": { "<目录/文件名>": { ... } }},键是相对runner/suite/test/的路径。每个条目支持的字段(README +mod.rsTestConfig+ schema):

字段类型作用
(空对象{}该用例登记为"应在 Deno 中通过",纳入 CI check
ignoreboolean所有平台跳过;mod.rs要求配ignore: true必须写reason
windows/darwin/linuxboolean 或期望失败对象布尔值控制该平台是否运行(默认true);写成{"exitCode": N, "output": "pattern"}表示"运行但期望以该方式失败"
linuxAarch64/linuxX86_64同上平台字段,按架构细分,覆盖linux
flakyboolean标记为 flaky,最多重试 3 次后才算失败
reasonstring说明跳过/标记原因
envobject仅对该用例追加的环境变量,叠加在 runner 默认值之上;README 明确提示 sparingly 使用
exitCode/outputinteger / string顶层期望失败配置,作用于所有平台(可被平台字段覆盖);output支持[WILDCARD]
extraDenoArgsstring 数组只对该用例追加的deno run/deno testCLI 参数
timeoutMsnumber覆盖该用例的超时(毫秒);README/mod.rs 提示只用于本来就慢的用例,不要拿来掩盖挂起

仓库中的真实条目示例(摘自 tests/node_compat/config.jsonc):

// 普通登记:期望通过 "parallel/test-assert-async.js": {}, // 只跳过 Windows(文档明确建议用逐平台开关而不是笼统 ignore) "internet/test-dns-ipv6.js": { "windows": false }, // 全平台跳过,必须带 reason "abort/test-zlib-invalid-internals-usage.js": { "ignore": true, "reason": "Tests Node.js internal C++ binding (internalBinding('zlib').Zlib) which is not implemented in Deno" }, // 标记为 flaky "parallel/test-child-process-can-write-to-stdout.js": { "flaky": true }, // 单用例环境变量覆盖(该测试需要走 OpenSSL 分支,其他用例不能带这个变量) "parallel/test-crypto-rsa-dsa.js": { "env": { "DENO_INTERNAL_NODE_TEST_FORCE_SHARED_OPENSSL": "1" } }

schema.json 里还给出期望失败的文档示例(平台字段写对象):"windows": { "exitCode": 1 }。语义(resolve_expected_failure/handle_expected_failure)是:该用例被运行,恰好以配置的方式失败(退出码相等、output[WILDCARD]模式匹配)才算通过;如果它通过了,或失败方式不符,都记为失败,失败信息里会给出Exit code mismatch/Output mismatch detail的具体差异。

运行细节与结果验证

  • 每个用例的实际执行:runner 用刚构建出的 deno 执行用例文件。用例源码中引用了node:test时用deno test -A --quiet --unsafe-proto --no-check,否则用deno run -A --quiet --unsafe-proto;工作目录是runner/suite/,并自动注入NODE_TEST_KNOWN_GLOBALS=0NODE_SKIP_FLAG_CHECK=1NO_COLOR=1TEST_SERIAL_ID等环境变量(mod.rsTestSetup)。
  • 用例内的// Flags::runner 会解析它,把--expose-gc等 V8 标志转成--v8-flags=,把--no-warnings等 Node 选项放进NODE_OPTIONS--inspect/--inspect=PORT会归一化成 Deno 的--inspect=127.0.0.1:PORT形式。
  • 超时:默认 10 000 ms,macOS 上 20 000 ms,可用timeoutMs逐用例覆盖。
  • 串行目录sequential/pummel/下的用例逐条串行执行(pummel 是 Node 的压力套件,会分配多 GB 缓冲区,并发跑会把 CI 机器拖垮)。
  • PTY 用例pseudo-tty/前缀的用例需要平台支持 PTY,不支持时自动记为 ignored。
  • flaky 处理flaky: true的用例最多跑 3 次;在 CI(IS_CI且非--report模式)下所有用例都按 flaky 处理。
  • 验证方式
    • 单用例:cargo test的输出显示ok/FAILED;失败时输出包含用例自身的 stdout/stderr(截断到 2000 字符),以及一行可复制的Command: NODE_TEST_KNOWN_GLOBALS=0 NODE_SKIP_FLAG_CHECK=1 NODE_OPTIONS='...' deno ...,按它可以直接复现失败(debugging_command_text)。
    • 全量:非--report模式下任何失败会触发panic_on_failures,即cargo test整体失败。
    • 历史结果:tests/node_compat/README.md 提到有每日结果查看站点(node-test-viewer),可看全部用例的最新结果。
  • CI 行为:README 明确 "The items listed inconfig.jsoncare checked in CI check" —— 你修好某个兼容问题、让新用例开始通过后,把它加进config.jsonc,它才会进入 CI 的必过集合;未登记的用例只在带过滤器的本地运行或--report模式下出现。

边界说明

  • doc/testing.md提醒:OS 相关跳过应使用逐平台开关(如"windows": false),而不是笼统的"ignore"ignore: truereason是强制的(缺失时mod.rs会 panic)。
  • config.jsonc里的键必须与runner/suite/test/下的相对路径一致(如parallel/test-foo.js),写错路径不会报错,只是该用例不会进入无过滤器运行集合。
  • 本文只覆盖 node compat 套件;node:*内置模块的 Deno 自写单元测试在tests/unit_node/,用cargo test unit_node::运行,是另一个独立入口。

【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/deno

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 18:55:27

Hermes智能体记忆外挂:分层设计、接入与排障

Hermes 这类智能体框架在单轮对话里可以回答得很漂亮&#xff0c;可一旦关掉窗口&#xff0c;它就像失忆了一样。给 Hermes 装上记忆外挂&#xff0c;真正要解决的并不是把模型底座换得更大&#xff0c;而是把用户偏好、历史结论、失败记录和任务状态保存下来&#xff0c;在下次…

作者头像 李华
网站建设 2026/9/9 18:54:54

Marlin 3D 打印机固件完整指南:5 步烧录并调好你的机器

Marlin 3D 打印机固件完整指南&#xff1a;5 步烧录并调好你的机器 【免费下载链接】Marlin Marlin is a firmware for RepRap 3D printers optimized for both 8 and 32 bit microcontrollers. Marlin supports all common platforms. Many commercial 3D printers come with …

作者头像 李华
网站建设 2026/9/9 18:54:47

MySQL 8.0.27保姆级安装教程:从下载到排错,Windows环境全流程详解

很多同学在群里问我&#xff0c;MySQL到底怎么装才能不翻车。说实话&#xff0c;MySQL 8.0.27这个版本在安装上已经比早期版本人性化不少&#xff0c;但网上教程经常只讲到“下一步下一步”&#xff0c;版本还停留在5.7的老流程&#xff0c;照着做很容易踩坑。我最近正好在一台…

作者头像 李华
网站建设 2026/9/9 18:53:52

TVBoxOSC 电视盒子播放器完整指南:3 步搞定全格式播放与直播源

TVBoxOSC 电视盒子播放器完整指南&#xff1a;3 步搞定全格式播放与直播源 【免费下载链接】TVBoxOSC TVBoxOSC - 一个基于第三方项目的代码库&#xff0c;用于电视盒子的控制和管理。 项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC TVBoxOSC 是一个开源的…

作者头像 李华
网站建设 2026/9/9 18:53:36

2026美赛冲刺:六类题型代码模板与备赛全攻略

2026年美赛已经进了最后的冲刺窗口&#xff0c;每年到这个时候&#xff0c;后台都会涌进一堆“求思路”“求代码”的消息。我这两年带队伍最大的感受是&#xff1a;美赛根本不比谁代码写得花哨&#xff0c;比的是谁能在有限时间内把题目转化成可计算的模型&#xff0c;再稳定地…

作者头像 李华