测试基础设施
🌐 Test Infrastructure
INFO
本文旨在邀请大家分享改进我们测试基础设施的想法,欢迎通过 Discord 与我们联系。
🌐 This article serves as an invitation for sharing ideas to improve our test infrastructure, feel free to contact us on Discord.
在 Oxc 中,正确性和可靠性被非常重视。
🌐 In Oxc, correctness and reliability are taken extremely seriously.
我们花费大量时间加强测试基础设施,以防止问题传播到下游工具。
🌐 We spend a great deal of time strengthening the test infrastructure to prevent problems from propagating to downstream tools.
解析器
🌐 Parser
一致性
🌐 Conformance
使用来自 Test262、Babel 和 TypeScript 的解析器测试来测试 JavaScript、TypeScript 和 JSX 语法。
🌐 Parser tests from Test262, Babel, and TypeScript are used to test JavaScript, TypeScript, and JSX syntax.
对于 Test262,包括所有第 4 阶段和正则表达式测试。
🌐 For Test262, all stage 4 and regular expression tests are included.
所有符合性结果都存储在快照文件中以便跟踪更改:
🌐 All conformance results are stored in a snapshot file for tracking changes:
所有语法错误都会写入这些快照文件中以便比较更改。
🌐 All syntax errors are written to these snapshot files for diffing changes.
模糊测试
🌐 Fuzzing
为了确保解析器在遇到随机数据时不会崩溃,使用了三种模糊测试器:
🌐 To ensure that the parser does not panic when encountering random data, three fuzzers are used:
- cargo fuzz 用于 向解析器发送随机字节。
- shift-fuzzer-js 由 bakkot 制作,用于生成随机但有效的 AST。
- 自动化模糊测试器 由 qarmin 开发,它会 主动报告 崩溃情况。
内存安全
🌐 Memory Safety
Oxc 使用基于 ['bumpalo'](https://docs.rs/bumpalo/latest/bumpalo) 的竞技场分配器作为其 AST 及其他数据的内存分配器。 AST节点类型中没有“Drop”实现。 编译时由 Oxc 的分配器强制执行,如果任何代码尝试在 arena 中分配 'Drop' 类型,就会引发编译时错误。这在静态上确保拥有堆分配数据的类型不会被存储在 arena 中,否则会导致内存泄漏。
🌐 Oxc uses an arena allocator based around bumpalo as the memory allocator for its AST, and other data. None of the AST node types have a Drop implementation. This is enforced at compile time by Oxc's allocator, which causes a compile-time error if any code attempts to allocate types in the arena which are Drop.This statically ensures that types which own heap-allocated data cannot be stored in the arena, which would result in memory leaks.
不安全代码
🌐 Unsafe code
Oxc 使用“unsafe”代码进行性能优化。我们的目标是将“unsafe”纳入自包含的数据结构中,并在外部提供安全的API。每个PR的箱子上都会跑Miri(https://github.com/oxc-project/oxc/actions/workflows/miri.yml)。
🌐 Oxc uses unsafe code for performance optimizations. We aim to contain unsafe to within self-contained data structures which present safe APIs externally. Miri is run on the crates containing these structures on every PR.
代码检查工具
🌐 Linter
快照诊断
🌐 Snapshot Diagnostics
所有的 linter 诊断信息都会写入一个 快照文件,以便测试防止回归。
🌐 All linter diagnostics are written to a snapshot file for testing against regressions.
例如:
🌐 For example:
⚠ typescript-eslint(adjacent-overload-signatures): All "foo" signatures should be adjacent.
╭─[adjacent_overload_signatures.tsx:3:18]
2 │ function foo(s: string);
3 │ function foo(n: number);
· ───
4 │ type bar = number;
5 │ function foo(sn: string | number) {}
· ───
6 │ }
╰────生态系统 CI
🌐 Ecosystem CI
oxc-ecosystem-ci 会对大型代码库运行 oxlint,以检查误报、回归和崩溃。测试的代码库包括:
- 滚动/滚动
- napi-rs/napi-rs
- toeverything/affine
- preactjs/preact
- 微软/VS代码
- bbc/simorgh
- elastic/kibana
- DefinitelyTyped/DefinitelyTyped
幂等性
🌐 Idempotency
幂等性测试用于所有工具的集成测试和端到端测试。
🌐 Idempotency testing is used for integration tests and end-to-end tests on all tools.
幂等性测试遵循以下步骤:
🌐 An idempotency test follows this procedure:
let sourceText = "foo";
let printed = tool(sourceText);
let printed2 = tool(printed);
assert(printed == printed2);例如,对一段代码进行幂等压缩应该产生相同的结果。
🌐 For example, idempotently minifying a piece of code should yield the same result.
所有工具(解析器、转换器、压缩器等)都在 Test262、Babel 和 TypeScript 测试文件上进行了幂等测试。
🌐 All tools (parser, transformer, minifer, etc.) are idempotently tested on Test262, Babel and TypeScript test files.
集成测试
🌐 Integration Tests
集成测试优于单元测试。
🌐 Integration tests are preferred over unit tests.
codecov 当前报告的 [][代码覆盖率网址] 行覆盖率。
端到端
🌐 End to End
代码库 monitor-oxc 对来自 npm-high-impact 的前3000个 npm 包进行了端到端测试。
🌐 The repository monitor-oxc performs end-to-end tests against the top 3000 npm packages from npm-high-impact.
它的 package.json 有 3000 个依赖:
🌐 Its package.json has 3000 dependencies:
"devDependencies": {
"@aashutoshrathi/word-wrap": "latest",
"@actions/http-client": "latest",
"@adobe/css-tools": "latest",
"@alloc/quick-lru": "latest",
...
"zip-stream": "latest",
"zod": "latest",
"zone.js": "latest",
"zustand": "latest"
}以及一个导入这些包并断言导入的测试文件:
🌐 And a test file that imports these packages and asserts the import:
src/dynamic.test.mjs
import test from "node:test";
import assert from "node:assert";
test("@aashutoshrathi/word-wrap", () => import("@aashutoshrathi/word-wrap").then(assert.ok));
test("@actions/http-client", () => import("@actions/http-client").then(assert.ok));
test("@adobe/css-tools", () => import("@adobe/css-tools").then(assert.ok));
test("@alloc/quick-lru", () => import("@alloc/quick-lru").then(assert.ok));
...
test("zod", () => import("zod").then(assert.ok));
test("zone.js", () => import("zone.js").then(assert.ok));
test("zustand", () => import("zustand").then(assert.ok));
test("zwitch", () => import("zwitch").then(assert.ok));在每个工具(codegen、transformer、minifier 等)重写 node_modules 中的所有文件之后,会运行此测试文件。
🌐 This test file is run after each of the tools (codegen, transformer, minifier, etc.) rewrites all the files in node_modules.
这些软件包每天都会更新到最新版本。
🌐 The packages are updated to their latest versions daily.
这个设置捕捉到许多一致性测试套件遗漏的隐晦错误。
🌐 This setup has caught many obscure bugs that the conformance test suites missed.
如果你对如何改进我们的测试基础设施有任何想法,请随时通过 Discord 联系我们。
🌐 If you any ideas on how to improve our test infrastructure, feel free to contact us on Discord.
