Skip to content

测试基础设施

🌐 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

使用来自 Test262BabelTypeScript 的解析器测试来测试 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:

  1. cargo fuzz 用于 向解析器发送随机字节
  2. shift-fuzzer-jsbakkot 制作,用于生成随机但有效的 AST。
  3. 自动化模糊测试器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:

javascript
 ⚠ typescript-eslint(adjacent-overload-signatures): All "foo" signatures should be adjacent.
  ╭─[adjacent_overload_signatures.tsx:3:18]
2function foo(s: string);
3function foo(n: number);
  ·                  ───
4type bar = number;
5function foo(sn: string | number) {}
  ·                  ───
6 │       }
  ╰────

生态系统 CI

🌐 Ecosystem CI

oxc-ecosystem-ci 会对大型代码库运行 oxlint,以检查误报、回归和崩溃。测试的代码库包括:

幂等性

🌐 Idempotency

幂等性测试用于所有工具的集成测试和端到端测试。

🌐 Idempotency testing is used for integration tests and end-to-end tests on all tools.

幂等性测试遵循以下步骤:

🌐 An idempotency test follows this procedure:

javascript
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:

json
"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

javascript
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.