rwilliamspbg-ops/RustForge
GitHub: rwilliamspbg-ops/RustForge
RustForge 是一套模块化的 Rust 测试套件模板,将编译器级覆盖率所需的各类测试工具与 CI 配置预先集成,让项目能以即插即用的方式获得生产级测试能力。
Stars: 1 | Forks: 0
# RustForge
[](https://github.com/rwilliamspbg-ops/RustForge/actions/workflows/ci.yml)
[](https://github.com/rwilliamspbg-ops/RustForge/releases)
[](#license)
[](#msrv)
RustForge 是一个模块化、易于采用的 Rust 测试套件模板,它可以从基础的 `cargo test` 工作流扩展到编译器级别的覆盖率。
## 为什么选择 RustForge?
大多数 Rust 项目最终都会构建自己的测试基础设施 —
拼凑 `cargo test`、Criterion、`proptest`、`cargo-fuzz`、
`trybuild`、`insta`、`cargo-llvm-cov`,以及将它们一致
运行的 CI 配置。RustForge 就是这套已经构建好、已经
接入 CI、并经端到端验证确实可用的基础设施 — 它是一个
起点,而不是需要你自己填充的骨架。
### 它与众不同的地方
- **真正的模块化** — 七个独立的分类 crate(`syntax`、
`semantic`、`performance`、`fuzz`、`integration`、`edge-cases`,
加上共享的 `core-tests`);只需采用你需要的部分。默认情况下,`cargo test --workspace`
不会引入任何额外依赖 — 更繁重的工具(Tokio、
Criterion、`proptest`、`trybuild`、`insta`)通过 feature flag 按需启用,
参见 [Feature Flags](#feature-flags)。
- **设计上力求全面** — 语法与编译失败测试、所有权/
语义正确性、带回归防护的 Criterion benchmark(外加
[统计基线对比](docs/performance-regression-testing.md))、
fuzzing(进程内的 `proptest` 和真正的 `cargo-fuzz` 目标,附带
[语料库管理指南](docs/fuzzing.md))、快照测试、边界/
边缘情况检查,以及跨分类的集成测试。所有这些确实在 CI 中运行,而不仅仅是在 README 示例中。
- **从第一天起即是生产级** — 多工具链、多操作系统 CI;MSRV
由专门的作业验证,而非仅仅声称;`cargo-deny` 供应链
检查;针对主工作空间和独立 `fuzz/` 工作空间的 Dependabot;
`#![warn(missing_docs)]` 作为硬性 CI 错误强制执行;issue/PR 模板
和贡献者清单。完整列表请参见 [工具与自动化](#tooling--automation)。
- **易于采用,没有锁定** — 是模板,不是框架。将其用作
GitHub 模板仓库,将 `crates/` 复制到现有工作空间(我们在实际测试
该流程时发现的一个真正陷阱请参阅上文的快速入门),或者提取单个
crate — 大多数仅依赖于共享的
`core-tests`,没有其他依赖。
- **与你共同扩展** — 从小型库上的 `syntax`/`semantic`/`integration`
开始;随着项目对严谨性要求的提高,逐步引入 fuzzing、属性测试
和带回溯防护的 benchmark。
### 适用人群
- 希望测试覆盖率为采用者所信任的库作者
- 正在构建生产级 Rust 服务,但不想从零开始组装这些
工具的团队
- 比起自行引导,更愿意从一个可运行且经过 CI 验证的基线
开始的人
## 工作空间布局
```
my-test-suite/
├── Cargo.toml
├── crates/
│ ├── core-tests/
│ ├── syntax-tests/
│ ├── semantic-tests/
│ ├── performance-tests/
│ ├── fuzz-tests/
│ ├── integration-tests/
│ └── edge-cases/
├── tests/
├── examples/
├── fuzz/
├── ci/
├── scripts/
└── docs/
```
## 快速入门(即插即用)
1. 将此仓库用作模板,或将 `Cargo.toml` + `crates/` 复制到你现有的工作空间中。
2. **如果要合并到现有工作空间**,请确保其根目录的 `Cargo.toml`
包含带有 `edition`、`rust-version` 和
`license` 的 `[workspace.package]` 表 — 这里的每个 crate 都通过 `.workspace = true` 继承这些设置,如果没有它,
`cargo test` 会立即失败(`workspace.package.edition was not
defined`)。请参阅
[`docs/adoption.md`](docs/adoption.md#common-pitfalls) 中的“常见陷阱” — 这是合并到现有项目时
最容易让人绊倒的 #1 问题,这是通过实际测试合并流程确认的,而非仅仅凭借假设。
3. 从核心分类(`syntax`、`semantic`、`integration`)开始。
4. 运行:
```
cargo test --workspace
```
5. 根据需要选择启用高级分类(`performance-tests`、`fuzz-tests`、`edge-cases`)及其
feature flag(`perf`、`fuzz`、`edge`) — 请参阅下方的 [Feature Flags](#feature-flags)。
## 模块职责
- `core-tests`:用于可重用断言和构建器的共享 fixture/helper。
- `syntax-tests`:面向解析器/语法的测试 — 包含 compile-fail/pass(`trybuild`)和快照(`insta`)测试。
- `semantic-tests`:所有权、借用、trait 和 async 语义。
- `performance-tests`:benchmark/perf 防护入口点。
- `fuzz-tests`:对 fuzz 友好的测试 harness 入口点。
- `integration-tests`:跨分类的端到端行为测试。
- `edge-cases`:边界值和健壮性检查。
## Feature Flags
可选的、会引入依赖的工具受 Cargo feature 的控制,因此默认情况下
`cargo test --workspace` 能保持快速。按 crate 或使用
`--all-features` 进行启用:
| Crate | Feature | 引入 | 解锁内容 |
| --- | --- | --- | --- |
| `core-tests` | `async` | `tokio` | async fixture 助手(`async_support::default_user_fixture_async`,并发 fixture 加载) |
| `core-tests` | `no_std` | — | 仅 `core` 的 helper 模块(`no_std_support`) |
| `semantic-tests` | `async` | `tokio` | 一个 async 所有权测试(`cargo test -p semantic-tests --features async`) |
| `performance-tests` | `perf` | `criterion` | `cargo bench -p performance-tests --features perf` |
| `fuzz-tests` | `fuzz` | `proptest` | 属性测试(`cargo test -p fuzz-tests --features fuzz`) |
| `edge-cases` | `edge` | — | 保护 `usize` 下溢/上溢的 checked 算术边界 helper(`overflow_checks`) |
| `syntax-tests` | `compile-fail` | `trybuild` | UI/compile-fail 测试(`cargo test -p syntax-tests --features compile-fail`) — CI 中仅固定在 stable 运行,详见 [`ci/README.md`](ci/README.md) |
| `syntax-tests` | `snapshot` | `insta` | 结构化快照测试(`cargo test -p syntax-tests --features snapshot`);使用 `cargo insta review` 更新 |
真正的 `cargo-fuzz` 脚手架位于 [`fuzz/`](fuzz) 中,它是一个独立
工作空间(参见 [`fuzz/README.md`](fuzz/README.md)),因为 fuzzing 需要
nightly 并且有其自己的依赖解析。使用以下命令构建它:
```
cd fuzz && cargo +nightly fuzz build
```
### MSRV
工作空间声明了 `rust-version = "1.75"` — 这是每个 crate 在**默认**
构建(无额外 feature)下的最低版本下限。引入活跃开发的生态系统工具的
可选 feature 可以独立于此模板需要更新的工具链,因为这些 crate 设置了它们自己的 MSRV:
- `fuzz-tests` 的 `fuzz` feature 将 `proptest` 固定在 `~1.8` 线上,
专门为了保持在 1.75 以内(proptest 1.9+ 需要 rustc 1.82+)。
- `syntax-tests` 的 `compile-fail` feature 将 `trybuild` 固定在 `=1.0.111`
出于同样的原因(1.0.112+ 需要 rustc 1.76+)。
- `performance-tests` 的 `perf` feature 依赖于 `criterion`,其自身的
依赖链(`clap`、`regex`、`plotters`、...)会跟随当前的 stable
Rust,并可能超过 1.75。运行
`cargo bench` 时请使用近期的 stable 工具链。
CI 的 `test` 作业在 stable/beta/nightly 上运行除
`compile-fail` 外的所有 feature(原因详见 [`ci/README.md`](ci/README.md)),因此它将
暴露这些工具链上任何未来的 MSRV 漂移。一个专门的 `msrv` 作业
针对 Rust 1.75 本身验证默认构建,而不是仅仅
在文档中断言该承诺。
## 工具与自动化
- 原生 `cargo test` 是一等公民。
- CI 是一个 8 作业流水线:跨 stable/beta/nightly
× ubuntu/windows/macos 矩阵的 `fmt`+`clippy`+测试,一个仅 stable 的 `nextest` 作业,一个仅 stable 的
`trybuild` 作业,一个 nightly 的 `fuzz-build` 作业(在每次 push/PR 时
针对每个目标进行构建 + 简短的冒烟测试运行,加上每日计划中的更长
活动 — 详见
[`docs/fuzzing.md`](docs/fuzzing.md)),一个仅 stable 的 `coverage` 作业,
一个 MSRV 作业,一个 `cargo-deny` 供应链作业,以及一个仅 stable 的 `docs`
作业。关于每个作业的作用及其如此
设定的原因,请参见
[`ci/README.md`](ci/README.md)。
- [`justfile`](justfile) — `just check`、`just test-all`、`just bench`、
`just fuzz-run `、`just coverage`、`just doc` 等等;运行
`just --list` 获取完整列表。`check`/`coverage` 方案调用的 `scripts/check.sh` 和
`scripts/coverage.sh` 也可以
独立工作,无需 `just`。详见 [`scripts/README.md`](scripts/README.md)。
- 每个 crate 的 `examples/` 目录下都有可运行的示例,例如:`cargo run -p core-tests --example fixture_walkthrough`。详见 [`examples/README.md`](examples/README.md)。
- 可选的生态系统工具在上述 feature 之下逐步引入
(`criterion`、`proptest`、`trybuild`、`cargo-fuzz`、`tokio`)或作为
独立的开发工具(`cargo-nextest`、`cargo-llvm-cov`、`cargo-deny`、
`just`) — 每一个都是按需启用,并在使用处附有文档,而不是
运行 `cargo test --workspace` 的硬性要求。
- 依赖清理:[`deny.toml`](deny.toml)(许可证/安全公告/禁用/来源,在 CI 中检查)和 [`.github/dependabot.yml`](.github/dependabot.yml)(针对主工作空间和独立 `fuzz/` 工作空间每周更新的 PR)。
## 覆盖率、报告与调试
推荐默认设置:
- 覆盖率:`scripts/coverage.sh` 或 `just coverage`(包含安装指南);或者手动运行:`rustup component add llvm-tools-preview &&
cargo install cargo-llvm-cov --locked`,然后执行 `cargo llvm-cov --workspace
--all-features --html`。也会在 CI 中作为可下载的 artifact 运行 — 参见
`coverage` 作业。
- 测试输出:`cargo test -- --nocapture`
- 替代运行器:`cargo nextest run --workspace`(安装:
`cargo install cargo-nextest --locked`) — 在大型测试套件上速度更快,每个
测试对应一个进程;不运行文档测试,因此它是补充而不是
替代 `cargo test`。
- 性能回归:运行 `just bench-baseline` 然后 `just bench-compare`
进行具有统计基础的比较前后对比 — 参见
[`docs/performance-regression-testing.md`](docs/performance-regression-testing.md)。
- 快照测试:`cargo insta review` 用于 `syntax-tests` 的 `snapshot`
feature — 参见 [`docs/adding-tests.md`](docs/adding-tests.md) 中的“Snapshot test”。
- 超出 CI 冒烟测试范围的 fuzzing:语料库/崩溃最小化、覆盖率、
阅读 ASan 输出 — 参见 [`docs/fuzzing.md`](docs/fuzzing.md)。
- CI artifact:失败时的日志、重现器和覆盖率报告
## 采用路线图
1. 基础:保留工作空间 + 共享 helper。
2. 分类:优先扩展语法/语义覆盖率。
3. 自动化:强制执行 CI 和覆盖率门禁。
4. 高级:添加 fuzz/属性/性能回归测试套件。
5. 完善:扩充文档/并维护贡献者清单。
有关增量推广指南,请参阅 `docs/adoption.md`。
## 贡献
关于贡献者清单以及
添加新测试分类的指南,请参见 [`CONTRIBUTING.md`](CONTRIBUTING.md)。
## 许可证
根据 [MIT](LICENSE-MIT) 或 [Apache-2.0](LICENSE-APACHE) 双重许可,由你
选择 — 这是 Rust 生态系统大部分项目所遵循的惯例。除非你
明确声明,否则根据 Apache-2.0 许可证的定义,任何有意提交以包含在
项目中的贡献,均应按上述方式进行双重许可,不附带任何
额外的条款或条件。
标签:Rust, 代码覆盖率, 可视化界面, 性能基准, 测试框架, 网络流量审计, 通知系统, 项目模板