# Testing

> 测试策略与规范。具体测试列表由 `<语言-specific 列举命令>` 自动产出，不在本文件维护。

## 测试金字塔

```
        ╱╲          E2E (端到端)
       ╱──╲         ~5%，覆盖核心 user journey
      ╱────╲
     ╱──────╲
    ╱────────╲      Integration (集成)
   ╱──────────╲     ~15%，跨模块协作
  ╱────────────╲
 ╱──────────────╲
╱────────────────╲  Unit (单元)
                    ~80%，单 fn / 单 class
```

**比例约束**：单元 : 集成 : E2E ≈ 80 : 15 : 5。E2E 多了说明集成抽象不足；单元少了说明逻辑泄露到集成。

## 工具链

| 类型 | 工具 | 用途 |
|---|---|---|
| 单元 | `<语言-specific 单测工具>` | 标准单测 |
| 集成 | `<集成测试运行器>` | 跨模块 |
| Property-based | `<property 库>` | 解析器 / 求值器 |
| Bench | `<bench 工具>` | 性能基线 |
| Mutation | `<mutation 工具>` | 季度检测测试盲区 |
| Coverage | `<coverage 工具>` | 行 + 分支覆盖 |
| Fuzz | `<fuzz 工具>` | 处理用户输入的解析器 |

## 测试组织

```
<项目目录约定占位>
├── src/                 ← 源码 + 就近单测
├── tests/               ← 集成测试
└── benches/             ← bench
```

跨模块的端到端测试放仓根 `tests/e2e/`。

## 写新测试的指南

### 单元测试

就近写在源文件附近。每个 public 函数至少：

- 一个 happy path
- 一个 edge case（空输入 / 边界值 / 错误输入）

### 集成测试

放 `tests/`，模拟真实使用，准备完整 fixture。

### E2E

放 `tests/e2e/`，spawn 真实 binary 或启动真实服务。

## CI 跑什么

每个 PR：

```bash
<build 命令>
<test 命令>
<lint 命令>
<format-check 命令>
koala-core check                  # dogfood: 用 koala 检自己
<coverage 命令>
```

main 分支额外：

```bash
<bench 命令>
<mutation 命令>                   # 慢，仅 main
<依赖审计命令>
```

## 不变量与测试的关系

部分 invariant 在 `koala-core::invariants` 表达为函数，测试同时验证。详见 [features/invariant-suite](features/invariant-suite.md)（如已建）。

## Property-based 用法

对解析器 / 求值器类代码强制 property test：parse 后 serialize 再 parse 必须等价（identity property）。

## Fuzz 目标

处理用户输入的解析器（drift detector / artifact parser / 配置加载）必须有 fuzz target。CI 跑数分钟，找到 panic / hang 即 fail。

## 性能基线

| 操作 | 当前 | 红线 |
|---|---|---|
| `<关键操作 1>` | <数值> | <红线> |
| `<关键操作 2>` | <数值> | <红线> |

超阈值 = PR 拒。

## Mutation testing

季度 pruning sprint 时跑。`MISSED` 数量 > 5% 表示有重要逻辑测试覆盖不足，立 issue 修。

## 测试反模式（禁止）

| 反模式 | 为什么禁止 |
|---|---|
| Mock 整个 fs / git | 集成测试要真跑 |
| 共享可变 fixture | 测试相互污染，难调试 |
| 没有 assertion 的"runs without panic"测试 | 无信息量 |
| `sleep(N)` 等待异步 | 用确定性同步原语 |
| 忽略错误返回值 | 错误路径不被覆盖 |

## 跨模块测试边界

仓根 `tests/integration/` 只放**只有跨模块才能验证**的场景：

- 完整生命周期（drift → invariant → workflow）
- CLI dispatch（`koala-core check` 调多个子模块）

避免在某模块测试里依赖其他模块的非 public API。

## 文档命令的 doctest

[runbook.md](runbook.md) 里的命令示例必须能跑通。CI 提取并真跑：

```bash
koala-core wiki extract-commands runbook.md > /tmp/runbook-commands.sh
bash /tmp/runbook-commands.sh
```

不通过 = 文档过期，PR 拒。

---

> 此文件由 koala-core init 创建。Tier 3（人写）。
