JairusSW/as-test
GitHub: JairusSW/as-test
一个运行时无关的 AssemblyScript 测试框架,提供模拟、快照、覆盖率与模糊测试,解决多运行时一致测试难题。
Stars: 8 | Forks: 0
╔═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╗
╠═╣ ╚═╗ ══ ║ ╠═ ╚═╗ ║
╩ ╩ ╚═╝ ╩ ╚═╝ ╚═╝ ╩
目录
- [为什么选择 as-test](#why-as-test)
- [安装](#installation)
- [文档](#docs)
- [项目结构](#project-layout)
- [编写测试](#writing-tests)
- [Mocking](#mocking)
- [快照](#snapshots)
- [模糊测试](#fuzzing)
- [运行时](#runtimes)
- [示例](#examples)
- [许可证](#license)
## 为什么选择 as-test
大多数 AssemblyScript 测试工具都与单一运行时绑定,通常是 Node.js。这在开发中可行,但无法反映代码在生产环境中的运行方式。
如果部署到 WASI、Wazero 或自定义运行时,你常常需要模拟所有内容,并为测试维护并行逻辑。
as-test 通过让你在实际目标运行时运行测试,同时仅模拟必要部分,解决了这一问题。
主要优势
- 运行时无关:可在 WASI、绑定或自定义运行器上测试
- 最小化模拟:尽可能使用真实导入
- 生产环境级测试:尽早捕获运行时特定问题
- 内联模拟和快照
- 自定义报告器和覆盖率
- 内置模糊测试支持
## 安装
最简单的启动方式是使用项目初始化器:
```
npx as-test init
```
这将生成一个基础配置文件、一个示例测试,以及可选的示例模糊测试器。
如果已有项目,只想安装包:
```
npm install --save-dev as-test
```
## 文档
完整文档位于:
## 项目结构
默认情况下,`as-test` 会查找:
- 测试文件位于 `assembly/__tests__`
- 模糊测试器位于 `assembly/__fuzz__`
- 配置文件为 `as-test.config.json`
生成的文件会存放在 `.as-test/` 目录中。
最小的 `as-test.config.json` 配置:
```
{
"input": ["assembly/__tests__/*.spec.ts"],
"output": ".as-test/",
"buildOptions": {
"target": "wasi"
},
"runOptions": {
"runtime": {
"cmd": "node .as-test/runners/default.wasi.js "
}
}
}
```
覆盖率点过滤可配置,以便忽略已知噪声间隙:
```
{
"coverage": {
"enabled": true,
"include": ["assembly/src/**/*.ts"],
"ignore": {
"labels": ["Call"],
"names": ["panic", "serialize"],
"locations": ["assembly/src/fuzz.ts:38:*"],
"snippets": ["*message: string*"]
}
}
}
```
## 编写测试
测试通常位于 `assembly/__tests__/*.spec.ts`。
示例:
```
import { describe, expect, test } from "as-test";
describe("math", () => {
test("adds numbers", () => {
expect(1 + 2).toBe(3);
});
});
```
运行全部测试:
```
npx ast test
```
通过自动工作池运行:
```
npx ast test --parallel
```
运行单个匹配文件:
```
npx ast test math
```
你无需学习所有 CLI 标志即可开始。大多数项目可以从 `npx ast test` 起步,仅在需要时添加更多配置。
## 模拟
支持模拟,但理念是谨慎使用。
使用 `as-test`,理想路径是针对真实运行时和真实导入运行代码。当这不切实际时,可以模拟单个导入,而不是围绕假行为重建整个环境。
对于本地函数,使用 `mockFn` 和 `unmockFn`。对于主机导入,使用 `mockImport` 和 `unmockImport`。
这在以下场景特别有用:
- 导入与外部世界通信
- 主机函数难以在测试中重现
- 你希望强制触发难以自然重现的边缘情况
这能让测试保持专注。你仍可在不使每个测试依赖真实运行时的情况下验证 AssemblyScript 逻辑。它也与快照配合良好,当你希望捕获模拟导入的输出并确保其随时间保持稳定时。
示例:
```
import { describe, expect, mockFn, test, unmockFn } from "as-test";
function getConfig(): string {
return "name=prod\nmode=live";
}
mockFn(getConfig, (): string => "name=demo\nmode=test");
describe("config", () => {
test("reads mocked data", () => {
expect(getConfig()).toContain("demo");
});
});
unmockFn(getConfig);
```
对于导入模拟,思路相同,但通常更简单的方式是将导入函数保留在一个小型包装模块中,并模拟该导入路径。
## 快照
当输出比精确步骤断言更重要时,快照非常有用。
它们适用于:
- 生成的字符串或结构化文本
- 序列化值
- 模拟导入的输出
- 较大的结果,逐字段检查会显得笨拙
这能让你在保持测试可读性的同时,锁住不应意外变化的行为。
示例:
```
import { describe, expect, test } from "as-test";
function renderReport(): string {
return "name=demo\nmode=test";
}
describe("report", () => {
test("matches the saved output", () => {
expect(renderReport()).toMatchSnapshot();
});
});
```
首次运行快照测试时,使用以下命令创建快照:
```
npx ast test --create-snapshots
```
之后,普通的 `npx ast test` 会验证它。
如果现有快照确实发生变化,使用以下命令覆盖:
```
npx ast test --overwrite-snapshots
```
## 模糊测试
模糊测试器通常位于 `assembly/__fuzz__/*.fuzz.ts`。
示例:
```
import { expect, FuzzSeed, fuzz } from "as-test";
fuzz("bounded integer addition", (left: i32, right: i32): bool => {
const sum = left + right;
expect(sum - right).toBe(left);
return sum >= i32.MIN_VALUE;
}).generate((seed: FuzzSeed, run: (left: i32, right: i32) => bool): void => {
run(seed.i32({ min: -1000, max: 1000 }), seed.i32({ min: -1000, max: 1000 }));
});
```
传递第三个参数以覆盖单个目标的运行次数,而不更改全局模糊测试配置:
```
fuzz("hot path stays stable", (): void => {
expect(1 + 1).toBe(2);
}, 250);
```
或将其作为 `.generate(...)` 的第二个参数传递:
```
fuzz("ascii strings survive concatenation boundaries", (input: string): bool => {
expect(input.length <= 40).toBe(true);
return true;
}).generate((seed: FuzzSeed, run: (input: string) => bool): void => {
run(seed.string({ charset: "ascii", min: 0, max: 40 }));
}, 250);
```
你仍可通过 CLI 覆盖模糊运行,以强制当前命令使用不同的运行次数:
```
npx ast fuzz --runs 500
npx ast fuzz --runs 1.5x
npx ast fuzz --runs +10%
npx ast fuzz --runs +100000
```
如果在初始化时使用了模糊示例,`as-test.config.json` 中已有相关配置。否则,添加一个 `fuzz` 块,以便 `npx ast fuzz` 知道要构建什么:
```
{
"fuzz": {
"input": ["./assembly/__fuzz__/*.fuzz.ts"],
"target": "bindings"
}
}
```
`ast fuzz` 会跨选定模式运行模糊文件,对每个文件报告一个结果,并保持最终汇总与普通测试分开。如果希望使用单个组合命令,请使用 `ast test --fuzz`。
当模糊测试失败时,`as-test` 会打印确切的失败种子及一次运行重现命令,例如 `ast fuzz ... --seed --runs 1`。崩溃记录在 `.as-test/crashes` 中,也包含传递给 `run(...)` 的输入,这有助于调试生成器本身的副作用。
仅运行模糊测试:
```
npx ast fuzz
```
同时运行测试和模糊测试:
```
npx ast test --fuzz
```
模糊测试在需要更广泛输入覆盖时可用,但不会干扰正常的测试流程。你可以从普通规格开始,稍后再添加模糊测试。
## 运行时
使用 `as-test` 的主要原因之一是你不必锁定到单一运行时。
如果项目运行在 WASI、绑定或自定义运行时下,你可以将测试指向该环境,而不是将 Node.js 视为唯一执行方式。
例如,`as-test.config.json` 中一个简单的 WASI 配置可能如下:
```
{
"input": ["./assembly/__tests__/*.spec.ts"],
"buildOptions": {
"target": "wasi"
},
"runOptions": {
"runtime": {
"cmd": "node ./.as-test/runners/default.wasi.js "
}
}
}
```
然后正常运行测试:
```
npx ast test
```
如果希望保留多个运行时,可使用模式:
```
{
"input": ["./assembly/__tests__/*.spec.ts"],
"modes": {
"wasi": {
"buildOptions": {
"target": "wasi"
},
"runOptions": {
"runtime": {
"cmd": "node ./.as-test/runners/default.wasi.js "
}
}
},
"bindings": {
"buildOptions": {
"target": "bindings"
},
"runOptions": {
"runtime": {
"cmd": "node ./.as-test/runners/default.bindings.js "
}
}
}
}
}
```
运行特定模式:
```
npx ast test --mode wasi
```
或
```
npx ast test --mode wasi,bindings
```
这是整个项目的核心理念:编写一次测试,然后选择与实际运行代码匹配的运行时。
## 示例
可运行的示例项目位于 [examples/](./examples/README.md)。它们适用于希望查看完整配置而非孤立代码片段的场景。
## 许可证
该项目采用开源许可证分发。开发出于热情,但如果你希望经济支持,可以向项目的 [GitHub Sponsors](https://github.com/sponsors/JairusSW) 页面捐款。
你可以通过以下链接查看完整许可证:[许可证](./LICENSE)
## 联系
请将所有问题提交至 [GitHub Issues](https://github.com/JairusSW/json-as/issues),如需交流,请发送邮件至 [me@jairus.dev](mailto:me@jairus.dev)
- **邮箱:** 发送咨询、问题或请求至 [me@jairus.dev](mailto:me@jairus.dev)
- **GitHub:** 访问官方仓库 [此处](https://github.com/JairusSW/json-as)
- **网站:** 访问我的官方网站 [jairus.dev](https://jairus.dev/)
- **Discord:** 联系我:[我的 Discord](https://discord.com/users/600700584038760448) 或 AssemblyScript Discord 服务器 [此处](https://discord.gg/assemblyscript/)标签:AssemblyScript, GNU通用公共许可证, MITM代理, Mocking, Node.js, npm, npx, SEO: AssemblyScript 测试, SEO: as-test, WASI, Wazero, WebAssembly, 代码覆盖率, 前端测试, 功能: 最小化 Mock, 功能: 生产级测试, 单元测试, 并行逻辑, 快照测试, 技术栈: TypeScript, 搜索词: WASI 测试框架, 搜索词: 运行时无关测试, 测试框架, 生产环境测试, 自定义报告器, 自定义脚本, 运行时无关, 集成初始化