ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Deno 测试体系全解:六大测试套件、spec 测试规范与 ./x 开发 CLI 实战

Deno 测试体系全解:六大测试套件、spec 测试规范与 ./x 开发 CLI 实战 Deno 测试体系全解六大测试套件、spec 测试规范与 ./x 开发 CLI 实战【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/denoDeno 仓库内置了覆盖 CLI 端到端、运行时 Web API、Node.js 兼容层、Web 平台标准与 Rust 底层逻辑的六层测试体系本文以仓库自带的 doc/testing.md 为核心脉络结合 tests/specs/mod.rs、tools/x.ts 等源码系统讲清每个套件的定位、目录结构、__test__.jsonc断言语言与./x开发命令的完整用法。读完后你可以准确判断“某个改动该写哪种测试”、独立编写 spec 测试并熟练用./x test-spec/./x test-unit等命令在本地复现 CI 的测试行为。套件总览先分清该找哪套测试Deno 有多个测试套件各自针对不同的代码层。doc/testing.md 给出的对照表如下套件位置测试对象Spec teststests/specs/CLI 命令端到端主集成测试Unit teststests/unit/运行时 / Web APIJS/TS 编写unit_nodetests/unit_node/node:*兼容层Node compattests/node_compat/Node 官方测试套件跑在 Deno 上WPTtests/wpt/Web Platform TestsWeb 标准符合性Rust tests遍布各 crateCrate 级 Rust 逻辑选择规则很简单凡是从命令行可观察到的行为——新 flag、子命令行为、错误信息、解析结果——都写 spec 测试只有从运行时内部断言才有意义的行为某个 Web API 的语义、Deno.*方法才写tests/unit/。各命令的权威速查在仓库根目录的 CLAUDE.md它自称是操作命令的 source of truthdoc/testing.md 则补充什么时候该用哪个套件的语境。spec 测试__test__.jsonc与输出断言语言spec 测试位于 tests/specs/是 Deno 的主集成测试形态每个测试目录包含一个__test__.jsonc清单文件描述一个或多个 step每个 step 是一次deno命令调用其输出被捕获并与期望匹配。测试名就是目录名。例如真实的 tests/specs/run/_001_hello/test.jsonc 只有三行{ args: run --reload 001_hello.js, output: 001_hello.js.out }创建一个新的 spec 测试只需四步在tests/specs/下建一个有描述性名字的目录添加描述 step 的__test__.jsonc放入测试所需的输入文件期望输出可内联在__test__.jsonc里也可放入.out文件。__test__.jsonc的三种形态从 tests/specs/mod.rs 的解析逻辑map_test_within_file/deserialize_value看清单文件按内容被识别为三种元数据单步测试SingleTestMetaData顶层直接是 step 字段如上面的 hello 例子会被自动包装成单元素steps多步测试MultiStepMetaData顶层含steps数组顺序执行多个命令多测试MultiTestMetaData顶层含tests对象一个目录展开为多个以目录名::测试名命名的测试共享目录级的envs、cwd、timeout、variants等配置。CLAUDE.md 给出的示例结构{ tests: { basic_case: { args: run main.ts, output: expected.out }, with_flag: { steps: [ { args: run --allow-net main.ts, output: [WILDCARD]success[WILDCARD] } ] } } }step 级可用字段来自源码的完整清单tests/specs/mod.rs中StepMetaData/MultiStepMetaData反序列化的字段即清单支持的全部配置camelCase字段含义args要执行的 deno 参数字符串或字符串数组output期望输出内联文本或以.out结尾的文件名exit_code期望退出码默认 0input标准输入内容以.in结尾时从该文件读取if条件执行windows、unix、mac、linux、notCI、notMacIntel、notWindowsArm、notSlowCiShard等见should_runenvs注入给命令的环境变量目录级与 step 级合并step 优先cwd该 step 的工作目录commandName覆盖默认被执行的 deno 可执行文件名flaky标记为 flaky失败时自动重试tempDir执行前把目录内非断言文件复制到临时目录断言文件自动排除ignore跳过该测试timeout每步超时秒数默认 300 秒repeat同一测试重复执行 N 次用于复现偶发问题variants参数化变体每个变体展开为测试名::变体名变体值以${name}占位符替换args/envs/output输出断言语言期望输出支持一套小型匹配语言字面字符即精确匹配[WILDCARD]匹配任意个任意字符含换行类似正则.*[WILDLINE]匹配任意个任意字符到行尾为止[WILDCHAR]匹配下一个任意字符[WILDCHARS(5)]匹配接下来任意 5 个字符[UNORDERED_START]…[UNORDERED_END]区间内的行可以乱序匹配应对非确定性输出如并发日志[# 注释]以[#开始、]结尾的行内注释。一个典型.out文件Check file://[WILDCARD]/main.ts [WILDCARD] Successfully compiled [WILDLINE]源码里还有两个实用约束值得知道见run_step内联output不得超过 160 字符超长会报错并提示你抽成.out文件以保证可读性.out文件与__test__.jsonc本身在tempDir模式下不会被复制进临时目录。schema 参考 tests/specs/schema.json。测试执行与 CI 优化机制从 tests/specs/mod.rs 的main()可以看到几个工程化细节收集策略使用TestPerDirectoryCollectionStrategy按目录取__test__.jsonc再经map_test_within_file展开这就是目录名即测试名的实现来源CI 哈希缓存check_ci_hash(specs, …)对tests/specs、tests/util、tests/testdata、tests/registry及 deno/test_server/denort 可执行文件做哈希PR 中这些内容未变化时整个 spec 套件直接跳过强制 filter 保护检测到CLAUDE_CODE_ENTRYPOINT环境变量AI 编码工具环境时不带测试过滤参数会直接 panic防止误跑全量 spec 套件分片支持ShardConfig::from_env()将测试切分到 CI shard运行期间由test_util::http_server()统一拉起本地 HTTP 服务供需要网络的用例使用。Unit 测试tests/unit/与tests/unit_node/tests/unit/ 下是 JS/TS 编写的运行时与 Web API 测试文件命名为*_test.ts如fetch_test.ts、console_test.ts、fs_events_test.ts等配合 tests/unit/README.md 使用。它们通过 cargo test harness 运行而不是裸的deno test——因为依赖 harness 的 setup。命令# 运行某个文件的全部单测 cargo test unit::webcrypto_test # 运行全部 unit 测试 cargo test unit:: # node 兼容层单测tests/unit_node/ cargo test unit_node::crypto_test cargo test unit_node::注意 CLAUDE.md 的明确警告不要用./target/debug/deno test直接跑这些文件。tests/unit_node/ 则是Deno 自研的node:*内建模块单测*_test.ts文件针对node:fs、node:crypto等 API 的行为断言与tests/node_compat/是完全不同的东西详见下一节。Node 兼容层测试别混淆 unit_node 与 node_compatdoc/testing.md 特别强调这两者经常被搞混tests/unit_node/— Deno 作者为node:*内建模块编写的单测tests/node_compat/—Node.js 官方自己的测试文件直接在 Deno 上执行以度量兼容度。tests/node_compat/README.md 说明了其结构runner/suite/— vendored 的 Node.js 测试用例git submodule来自 denoland/node_testconfig.jsonc— 声明哪些 Node 测试用例在 Deno 中应通过以及每个用例的平台/行为配置mod.rs— node compat 测试的 cargo 入口。config.jsonc中每个用例条目支持的可选项flaky布尔标记为 flaky 的用例最多运行 3 次后才算失败windows布尔是否允许在 Windows 上运行默认true按平台的跳过使用逐 OS 的布尔 flag例如windows: false而不是笼统的ignore字段。当前 tests/node_compat/config.jsonc 已累积了数千行配置。跑单个 Node 测试用例cargo test name of test fileWPTWeb 标准符合性tests/wpt/ 存放上游 Web Platform Tests用于检查 fetch、streams 等 Web API 的标准符合性。CI 中只在 Linux 上运行。tests/wpt/README.md 记录了 WPT 的检出与同步方式。Rust 测试与 libs 层的隔离性设计Rust 侧用标准cargo testCI 中对deno_core/libs/*系列 crate 使用cargo nextest以并行提速。libs/下的底层 crate 被设计为可独立测试但部分 crate 需要与兄弟 crate 一起选中才能编译——具体坑位见 CLAUDE.md 与仓库项目记忆。./x test-core复现的就是 CI 中 deno_core 测试 job 的完整命令组合cargo nextest run --features deno_core/default deno_core/unsafe_use_unprotected_platform deno_core/v8 \ --tests --examples \ -p deno_core -p deno_v8 -p build-your-own-js-snapshot -p dcore -p deno_ops \ -p deno_ops_compile_test_runner -p serde_v8 -p deno_core_testing # 之后补跑编译测试 runner 与文档测试运行各套件./x开发 CLI 全解仓库根目录的 x 是一个极薄的入口脚本#!/usr/bin/env -S deno run --allow-all实际实现是 tools/x.ts——一个受 Servo mach 工具启发的开发者 CLI为常用构建/测试任务提供统一入口。./x --help列出全部命令命令底层实现说明./x setupcargo build --bin deno --bin test_server克隆仓库后初始化编译 deno 与测试用 test_server./x buildcargo build --bin deno调试模式编译 deno 到target/debug/deno./x checkcargo check快速编译检查跳过链接不产出二进制./x test-spec filtercargo test -p specs_tests --test specs -- filterspec 集成测试./x test-unit filtercargo test -p unit_tests --test unit -- filter运行时单测./x test-node filtercargo test -p unit_node_tests --test unit_node -- filternode:*单测./x test-compat filtercargo test --test node_compat -- filterNode 官方兼容测试./x test-core [filter]上文 nextest 组合命令deno_core 及关联 crate 测试需cargo binstall cargo-nextest./x test-napi [filter]cargo build -p test_napideno test … tests/napi/NAPI 原生插件测试加载 cdylib 并从 JS 调用导出函数源码在tests/napi/src/./x fmtdeno run -A tools/format.jsdprint 全仓库格式化./x lintdeno run -A tools/lint.jsJS/TS Rust 全量 lint./x lint-jsdeno run -A tools/lint.js --js仅 lint JS/TS未改 Rust 时更快./x verify./x fmt ./x lint-js提交前最小验证所有test-*命令都要求过滤参数对测试名做子串匹配也可用--list先列出可用测试例如./x test-spec --list # 列出全部 spec 测试 ./x test-spec fmt # 跑名字含 fmt 的 spec 测试 ./x test-unit streams # 跑名字含 streams 的单测 ./x test-compat fs # 跑 node 兼容层中 fs 相关用例提交前检查流程doc/testing.md 与 CLAUDE.md 一致运行tools/format.js格式化再运行对应的tools/lint.js——如果只改了 JS/TS用tools/lint.js --js即可动了 Rust 则必须跑完整tools/lint.js含 clippy。CI 里跑什么以及 docs-only 快速通道PR 触发时CI 在受支持平台上构建 Deno并运行 spec、unit、node-compat 与 WPT 套件外加deno_corecrate 测试与 lint。CI 工作流是生成的源码真值是 .github/workflows/ci.ts由它写出.github/workflows/ci.generated.yml从不手改 yml。一个值得注意的例外详见 doc/ci.md只修改doc/目录的 PR 只跑lintjob其余全部跳过——因为 Markdown 改动不可能影响二进制。其机制是pre-buildjob 调用 tools/check_docs_only_changes.js 对 PR 与 base SHA 做 diff若所有变更文件都在doc/下则输出docs_onlytrue各构建/测试 job 的if:条件据此跳过lintjob 刻意不被该 flag 门控保证 Markdown 仍会被deno fmt --check格式化检查ci-status聚合 job 把被跳过的依赖计为无害故分支保护规则正常变绿。一旦 PR 同时触碰doc/之外的任何文件docs_only归 false完整流水线照常运行。常见测试问题的排查要点CLAUDE.md 的 Troubleshooting 一节给出了 spec 测试失败时的处理路径仔细 diff 测试输出与期望的差异输出格式被有意修改时更新对应.out文件对非确定性输出使用[WILDCARD]flaky 场景优先加[UNORDERED_START]/[UNORDERED_END]做顺序无关匹配其次检查测试代码里的竞态必要时在清单中设置flaky/timeout字段spec 清单支持或在 node_compat 的config.jsonc中把用例标记为flaky: true权限类失败确认测试 setup 授予了所需权限。小结Deno 的测试体系是按可观察层面分层的典型设计命令行可观察行为进tests/specs/__test__.jsonc 通配断言语言运行时内部语义进tests/unit/Node 兼容度用自研单测 Node 官方用例双轨验证tests/unit_node/tests/node_compat/config.jsoncWeb 标准交给 WPTRust 逻辑用cargo test/cargo nextest隔离验证。开发时统一用./x系列命令按过滤词快速定位测试提交前以./x verify为最小门槛理解了pre-build的docs_only门控后你也能预判任何一类改动在 CI 中会触发哪些 job。【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/deno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表