rwilliamspbg-ops/RustForge

GitHub: rwilliamspbg-ops/RustForge

RustForge 是一套模块化的 Rust 测试套件模板,将编译器级覆盖率所需的各类测试工具与 CI 配置预先集成,让项目能以即插即用的方式获得生产级测试能力。

Stars: 1 | Forks: 0

# RustForge [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/rwilliamspbg-ops/RustForge/actions/workflows/ci.yml) [![Release](https://img.shields.io/github/v/release/rwilliamspbg-ops/RustForge?include_prereleases&label=release)](https://github.com/rwilliamspbg-ops/RustForge/releases) [![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](#license) [![MSRV: 1.75](https://img.shields.io/badge/MSRV-1.75-blue.svg)](#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, 代码覆盖率, 可视化界面, 性能基准, 测试框架, 网络流量审计, 通知系统, 项目模板