# 测试与质量

> ServerBee 如何通过分层自动化测试和按变更路径执行的 CI 门槛，验证 Rust、WebSocket 与前端行为。

URL: https://docs.serverbee.app/zh/docs/testing

ServerBee 把可靠性视为产品能力。代码库提供一套规模大、运行快的自动化测试，覆盖从 Rust 逻辑、实时 WebSocket 控制面到 React 界面的完整链路。CI 会根据触发事件和变更路径执行相应的质量检查。

## 测试分层一览 [#测试分层一览]

| 范围             | 覆盖内容                                                  |
| -------------- | ----------------------------------------------------- |
| `common` crate | 协议消息、能力位掩码、SSRF 防护、共享类型                               |
| `agent` crate  | 采集器、reporter WebSocket 循环、pinger、文件管理、安全检测器、防火墙、IP 质量 |
| `server` crate | REST 处理器、WebSocket 处理器、服务层、后台任务、数据库迁移                 |
| 前端（`apps/web`） | Hook、组件、状态存储和工具函数（Vitest）                             |

这些层级合计包含 **3,800 项以上的自动化测试**。测试数量会随着覆盖范围扩大而变化，因此本页记录稳定的测试分层和检查命令，不逐项维护某个时间点的精确数量。

## 我们怎么测 [#我们怎么测]

ServerBee 采用分层策略，为每一层选择合适的测试方式。

### 单元测试 [#单元测试]

纯逻辑就近放在源文件的内联 `#[cfg(test)]` 模块中测试，包括协议序列化与反序列化、能力位掩码、SSRF 防护、告警评估、成本计算、解析器和采集器。这类测试通常在毫秒级完成，构成 `agent` 与 `common` 测试套件的主体。

### 集成测试 [#集成测试]

服务端集成测试通过 HTTP 和 WebSocket 直接驱动**真实的 Axum 路由**，并使用完成全新迁移的独立 SQLite 数据库。专用的 **mock-agent 测试桩**（`crates/server/tests/common/mod.rs`）通过真实 WebSocket 连接启动模拟 Agent，无需真实主机即可端到端验证控制面：

* 终端中继、Docker 日志流、文件操作、定时任务派发
* 实时浏览器广播（首次全量同步和后续增量更新）
* 安全事件、告警、能力门控，以及 Admin/Member 权限

在 Agent 侧，reporter 的“连接 → 握手 → 派发 → 重连”主循环由**进程内的模拟 WebSocket 服务器**驱动，无需真实后端即可测试网络核心。

### 前端测试 [#前端测试]

React 应用使用 [Vitest](https://vitest.dev) 测试 Hook、组件、状态存储和工具函数。运行 `make web-test` 即可执行前端测试套件。

<Callout type="info">
  这套集成测试桩让贡献者可以在笔记本电脑上验证真实的请求、响应和 WebSocket 流程，无需 Agent、Docker 守护进程或外部服务。
</Callout>

## 覆盖率 [#覆盖率]

覆盖率使用 [`cargo-llvm-cov`](https://github.com/taiki-e/cargo-llvm-cov) 测量：

| Crate    | 区域覆盖率 | 行覆盖率 |
| -------- | ----- | ---- |
| `common` | 98%   | 97%  |
| `agent`  | 90%   | 90%  |
| `server` | 92%   | 93%  |

Rust 总体区域覆盖率超过 91%。当前较大的剩余缺口集中在进程启动和依赖真实环境的 I/O 路径，包括 Docker 守护进程、Linux 内核设施（nftables / conntrack / journald）、原始 ICMP 套接字、PTY，以及 OAuth、SMTP、APNs 等外部服务。在可行范围内，这些环境相关路径通过集成测试桩和 `tests/` 目录下的手动端到端检查清单演练。

## 本地运行测试 [#本地运行测试]

```bash
make cargo-test     # Rust: unit + integration across the workspace
make web-test       # Frontend: Vitest
make cargo-clippy   # Rust lint (0 warnings enforced)
```

测量单个 crate 的覆盖率：

```bash
cargo llvm-cov -p serverbee-server --summary-only
```

## CI 门槛 [#ci-门槛]

主 CI 工作流在向 `main` 分支 push 以及以 `main` 为目标的 Pull Request 时运行。只改动 Markdown、MDX、`docs/` 或 iOS 的变更不会触发它。其余情况下，第一个任务会把变更文件与基准提交对比，只运行受影响领域的检查：

| 领域   | 变更路径                                                                          | 检查                                        |
| ---- | ----------------------------------------------------------------------------- | ----------------------------------------- |
| Rust | `crates/`、Cargo manifest、`.cargo/`、工具链文件、内置 widget 源码与前端构建配置                  | `cargo check`、零警告 Clippy、Rust 测试任务        |
| Web  | `apps/web/`、`packages/`、根目录 `package.json`、`bun.lock`、`tsconfig`、`turbo.json` | 前端构建、类型检查、Vitest 测试                       |
| Lint | Biome 处理的任意文件（JS/TS、JSON、CSS）或 `biome.json`                                   | Ultracite lint                            |
| 安装脚本 | `deploy/install.sh`、`scripts/extract-changelog.sh` 及其测试                       | 安装脚本事务测试，以及 POSIX、BusyBox 和 ShellCheck 验证 |

服务端集成测试会用到内嵌的 SPA 和内置 widget，因此 widget 与前端构建配置的变更也会运行 Rust 检查。修改任何工作流文件、新建分支，或 push 时没有可用的基准提交，都会运行全部检查。iOS 工作流在 `apps/ios/` 下除 Markdown 以外的文件变更时运行；文档工作流在 `apps/docs/` 及其契约检查涉及的文件变更时运行。

每个 Pull Request 还会运行 **Check commit attribution**，拒绝提交、标题和描述中出现的 `Co-authored-by` trailer、“Generated by/with”加 Agent 名称的文字以及邮箱地址。同样的规则也会在本地通过 Lefthook 的 `commit-msg` hook 执行。

发布构建会为五个目标交叉编译二进制文件（Linux x86\_64/aarch64 musl、macOS x86\_64/aarch64、Windows x86\_64），并发布多架构 Docker 镜像。
