Files
xsl 93b88db2f5 test: unit suite for the gateway invariants plus an integration slice
Covers routing, failover, the circuit breaker, structured-output retries, the
cache-prefix validator, cost computation including cached-token pricing, the
daily budget breaker, the quota protocol, the task state machine and log
redaction. HTTP is mocked -- no unit test spends money. The integration test
runs the real slice against PostgreSQL and Redis with a faked provider.
2026-08-14 00:26:39 +08:00

49 lines
2.2 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `tests/`
| 目录 | 内容 | 依赖 |
| --- | --- | --- |
| `unit/` | 领域逻辑、LLM 网关、脱敏、错误码 | 无。不许连库、不许发网络请求 |
| `integration/` | 带 PostgreSQL / Redis 的链路 | `make up`,或 testcontainers |
| `golden/` | 黄金集回归(检索 / 规则 / 报告) | 尚未建立,见下 |
```bash
make test-unit # 默认只跑 unit(integration 自动跳过)
MEIDA_RUN_INTEGRATION=1 uv run pytest -m integration
```
## 覆盖率门槛
`pytest` 对 `packages/llm` 与 `packages/domain` 统计覆盖率,低于阈值即失败。
这两个包是 mypy strict 的范围,也是业务正确性的核心,其他层靠集成测试覆盖。
## 绝对不要做的事
- **不要在单测里调用真实的 DeepSeek**。`scripts/smoke.sh` 是唯一会真的花钱的
入口。单测用 `httpx.MockTransport` 或 `tests/unit/test_gateway.py` 里的
`FakeProvider`。
- 不要 `time.sleep()`。熔断器、预算闸门都支持注入时钟。
- 不要断言日志文本。断言行为。
## 黄金集(还没建,但这是最重要的一道防线)
架构 §16.2:
> AI 改代码时最容易破坏的是那些「没有断言保护的隐性行为」。检索链路和规则引擎
> 必须有一套固定输入 → 期望输出的样本集。
M2 落地知识库时必须同步建立(FR-KB-11,≥ 100 条用例):
检索 Top-5 命中率 ≥ 80%、硬过滤零漏、规则命中正确性、报告结构完整性、
**硬性禁忌违反数 = 0**。指标退化即阻断合并。
## 已覆盖的关键不变量
| 测试 | 保护的是什么 |
| --- | --- |
| `test_prompt_cache_prefix.py` | 固定前缀不含易变 token,否则输入成本翻数倍 |
| `test_daily_budget.py` | 日成本超限时**拒绝**非关键调用,不是只告警 |
| `test_gateway.py` | 路由、故障转移、熔断、结构化重试、每次调用都记成本 |
| `test_quota_domain.py` | 预扣三段式;退还幂等;服务端硬校验 |
| `test_task_state.py` | 任务状态机没有非法跃迁 |
| `test_log_redaction.py` | 手机号 / 令牌 / 密钥 / 诊断结论不进日志 |
| `test_response_envelope.py` | 每个错误码都有文案;配额文案不含价格字样 |