Files
ds2api/docs/TESTING.md

259 lines
7.1 KiB
Markdown
Raw 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.
# DS2API 测试指南
语言 / Language: 中文 + English同页
## 概述 | Overview
DS2API 提供两个层级的测试:
| 层级 | 命令 | 说明 |
| --- | --- | --- |
| 单元测试Go | `./tests/scripts/run-unit-go.sh` | 不需要真实账号 |
| 单元测试Node | `./tests/scripts/run-unit-node.sh` | 不需要真实账号 |
| 单元测试(全部) | `./tests/scripts/run-unit-all.sh` | 不需要真实账号 |
| 端到端测试 | `./tests/scripts/run-live.sh` | 使用真实账号执行全链路测试 |
端到端测试集会录制完整的请求/响应日志,用于故障排查。
Node 单元测试脚本会先做 `node --check` 语法门禁,再以 `--test-concurrency=1` 串行执行测试文件,减少模块级共享状态带来的干扰。
---
## 快速开始 | Quick Start
### 单元测试 | Unit Tests
```bash
./tests/scripts/run-unit-all.sh
```
```bash
# 或按语言拆分执行
./tests/scripts/run-unit-go.sh
./tests/scripts/run-unit-node.sh
```
```bash
# 结构与流程门禁
./tests/scripts/check-refactor-line-gate.sh
./tests/scripts/check-node-split-syntax.sh
# 发布阻断:阶段 6 手工烟测签字检查(默认读取 plans/stage6-manual-smoke.md
./tests/scripts/check-stage6-manual-smoke.sh
```
### 端到端测试 | End-to-End Tests
```bash
./tests/scripts/run-live.sh
```
**默认行为**
1. **Preflight 检查**
- `go test ./... -count=1`(单元测试)
- `./tests/scripts/check-node-split-syntax.sh`Node 拆分模块语法门禁)
- `node --test tests/node/stream-tool-sieve.test.js tests/node/chat-stream.test.js tests/node/js_compat_test.js`
- `npm run build --prefix webui`WebUI 构建检查)
2. **隔离启动**:复制 `config.json` 到临时目录,启动独立服务进程
3. **场景测试**
- ✅ OpenAI 非流式 / 流式
- ✅ Claude 非流式 / 流式
- ✅ Admin API登录 / 配置 / 账号管理)
- ✅ Tool Calling
- ✅ 并发压力测试
- ✅ Search 模型
4. **结果收集**:继续执行所有用例(不中断),写入最终汇总
如果你只想跳过这些 preflight 检查,可以直接运行 `go run ./cmd/ds2api-tests --no-preflight`
---
## CLI 参数 | CLI Flags
```bash
go run ./cmd/ds2api-tests \
--config config.json \
--admin-key admin \
--out artifacts/testsuite \
--port 0 \
--timeout 120 \
--retries 2 \
--no-preflight=false \
--keep 5
```
| 参数 | 说明 | 默认值 |
| --- | --- | --- |
| `--config` | 配置文件路径 | `config.json` |
| `--admin-key` | Admin 密钥 | `DS2API_ADMIN_KEY` 环境变量,回退 `admin` |
| `--out` | 产物输出根目录 | `artifacts/testsuite` |
| `--port` | 测试服务端口(`0` = 自动分配空闲端口) | `0` |
| `--timeout` | 单个请求超时秒数 | `120` |
| `--retries` | 网络/5xx 请求重试次数 | `2` |
| `--no-preflight` | 跳过 preflight 检查 | `false` |
| `--keep` | 保留最近几次测试结果(`0` = 全部保留) | `5` |
---
## 自动清理 | Auto Cleanup
每次测试运行完成后,程序会自动扫描输出目录(`--out`),按时间排序保留最近 `--keep` 次运行的结果,超出部分自动删除。
- 默认保留 **5**
- 设置 `--keep 0` 可关闭自动清理
- 被删除的旧运行目录会打印日志提示
---
## 产物结构 | Artifact Layout
每次运行会创建一个以运行 ID 命名的目录:
```text
artifacts/testsuite/<run_id>/
├── summary.json # 机器可读报告
├── summary.md # 人类可读报告
├── server.log # 测试期间服务端日志
├── preflight.log # Preflight 命令输出
└── cases/
└── <case_id>/
├── request.json # 请求体
├── response.headers # 响应头
├── response.body # 响应体
├── stream.raw # 原始 SSE 数据(流式用例)
├── assertions.json # 断言结果
└── meta.json # 元信息(耗时、状态码等)
```
---
## Trace 关联 | Trace Binding
每个测试请求自动注入 trace 信息,便于快速定位问题:
| 位置 | 格式 |
| --- | --- |
| 请求头 | `X-Ds2-Test-Trace: <trace_id>` |
| 查询参数 | `__trace_id=<trace_id>` |
当用例失败时,`summary.md` 中会包含 trace ID。你可以快速搜索对应的服务端日志
```bash
rg "<trace_id>" artifacts/testsuite/<run_id>/server.log
```
---
## 退出码 | Exit Code
| 退出码 | 含义 |
| --- | --- |
| `0` | 所有用例通过 ✅ |
| `1` | 有用例失败 ❌ |
可将测试集作为本地发布门禁使用CI/CD 集成)。
---
## 安全提醒 | Sensitive Data Warning
⚠️ 测试集会存储**完整的原始请求/响应载荷**用于调试。
- **不要**将 artifacts 目录上传到公开仓库
- **不要**在 Issue tracker 中分享未脱敏的 artifact 文件
- 如需分享日志请先手动清除敏感信息token、密码等
---
## 常见用法 | Common Usage
### 仅跑单元测试
```bash
go test ./...
```
### 运行特定模块的单元测试
```bash
# 运行 tool calls 相关测试(推荐用于调试 tool call 解析问题)
go test -v -run 'TestParseToolCalls|TestRepair' ./internal/util/
# 运行单个测试用例
go test -v -run TestParseToolCallsWithDeepSeekHallucination ./internal/util/
# 运行 format 相关测试
go test -v ./internal/format/...
# 运行 adapter 相关测试
go test -v ./internal/adapter/openai/...
```
### 调试 Tool Call 问题 | Debugging Tool Call Issues
当遇到 DeepSeek 工具调用解析问题时,可以使用以下方法:
```bash
# 1. 运行 tool calls 相关的所有测试
go test -v -run 'TestParseToolCalls|TestRepair' ./internal/util/
# 2. 查看测试输出中的详细调试信息
go test -v -run TestParseToolCallsWithDeepSeekHallucination ./internal/util/ 2>&1
# 3. 检查具体测试用例的修复效果
# 测试用例位于 internal/util/toolcalls_test.go包含
# - TestParseToolCallsWithDeepSeekHallucination: DeepSeek 典型幻觉输出
# - TestRepairLooseJSONWithNestedObjects: 嵌套对象的方括号修复
# - TestParseToolCallsWithMixedWindowsPaths: Windows 路径处理
```
### 运行 Node.js 测试
```bash
# 运行 Node 测试
node --test tests/node/stream-tool-sieve.test.js
# 或使用脚本
./tests/scripts/run-unit-node.sh
```
### 跑端到端测试(跳过 preflight
```bash
go run ./cmd/ds2api-tests --no-preflight
```
### 运行原始流仿真(独立工具)
```bash
./tests/scripts/run-raw-stream-sim.sh
```
说明:
- 该工具会重放 `tests/raw_stream_samples` 下全部样本,按上游 SSE 顺序做 1:1 仿真解析。
- 默认校验不出现 `FINISHED` 文本泄露,并要求存在结束信号。
- 结果会写入 `artifacts/raw-stream-sim/*.json`,可供其他测试脚本或排障流程复用。
### 指定输出目录和超时
```bash
go run ./cmd/ds2api-tests \
--out /tmp/ds2api-test \
--timeout 60
```
### 在 CI 中使用
```bash
# 确保 config.json 存在且包含有效测试账号
./tests/scripts/run-live.sh
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "Tests failed! Check artifacts for details."
exit 1
fi
```