195 lines
4.8 KiB
Markdown
195 lines
4.8 KiB
Markdown
|
|
# Go 主测试链路对齐方案
|
|||
|
|
|
|||
|
|
- 版本:v1.0
|
|||
|
|
- 日期:2026-03-18
|
|||
|
|
- 目标:将测试体系与主技术栈(Go + PostgreSQL)对齐,替代 Python 工程骨架为主的测试设计。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 适用范围
|
|||
|
|
|
|||
|
|
1. 适用于网关主链路:路由、鉴权、计费、适配器、风控、审计。
|
|||
|
|
2. 覆盖阶段:S0-S2(优先保障 S1/S2 的上线与替换门禁)。
|
|||
|
|
3. 本文档作为测试实施主方案,历史 Python 示例仅保留参考。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 测试金字塔(Go版)
|
|||
|
|
|
|||
|
|
| 层级 | 占比 | 工具 | 目标 |
|
|||
|
|
|---|---:|---|---|
|
|||
|
|
| 单元测试 | 70% | `go test` + `testing` + `testify` | 逻辑正确性、异常分支、边界条件 |
|
|||
|
|
| 集成测试 | 20% | `go test` + `testcontainers-go` + `httptest` | DB/Redis/网关链路联通与一致性 |
|
|||
|
|
| E2E/门禁测试 | 10% | `playwright` + `k6` + 契约回归脚本 | 用户旅程、性能门禁、兼容门禁 |
|
|||
|
|
|
|||
|
|
覆盖率目标:
|
|||
|
|
1. 核心包总覆盖率 >= 80%。
|
|||
|
|
2. Router/Billing/Adapter 覆盖率 >= 85%。
|
|||
|
|
3. 关键门禁用例(S2 Gate)通过率 = 100%。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 测试目录与命名规范
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
立交桥/
|
|||
|
|
gateway/
|
|||
|
|
internal/
|
|||
|
|
pkg/
|
|||
|
|
tests/
|
|||
|
|
unit/
|
|||
|
|
router/
|
|||
|
|
billing/
|
|||
|
|
auth/
|
|||
|
|
integration/
|
|||
|
|
api/
|
|||
|
|
db/
|
|||
|
|
adapter/
|
|||
|
|
contract/
|
|||
|
|
compat/
|
|||
|
|
e2e/
|
|||
|
|
user_journey/
|
|||
|
|
performance/
|
|||
|
|
k6/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
命名规则:
|
|||
|
|
1. 单元测试文件:`*_test.go`。
|
|||
|
|
2. 集成测试标签:`//go:build integration`。
|
|||
|
|
3. 门禁测试标签:`//go:build gate`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 工具链基线(Go)
|
|||
|
|
|
|||
|
|
| 能力 | 工具 | 说明 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 单元测试 | `testing`, `testify/require` | 断言与失败信息可读性 |
|
|||
|
|
| Mock | `gomock` 或 `testify/mock` | 仅在外部依赖边界处使用 |
|
|||
|
|
| HTTP测试 | `httptest` | Handler/中间件测试 |
|
|||
|
|
| DB集成 | `testcontainers-go` + PostgreSQL 15 | 与生产数据库方言一致 |
|
|||
|
|
| Redis集成 | `testcontainers-go` + Redis 7 | 限流/并发门控验证 |
|
|||
|
|
| 覆盖率 | `go test -coverprofile` | CI 门禁 |
|
|||
|
|
| 性能 | `k6` | P95/P99 与错误率门禁 |
|
|||
|
|
| 前端E2E | `playwright` | 注册、Key、调用、账单旅程 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 关键测试套件(必须落地)
|
|||
|
|
|
|||
|
|
### 5.1 Router Core 套件
|
|||
|
|
|
|||
|
|
1. 主路径端点归一:`/responses` -> `/v1/responses`。
|
|||
|
|
2. 路由决策正确性:模型映射、租户策略、fallback。
|
|||
|
|
3. 接管率标记:`router_engine` 写入一致性。
|
|||
|
|
|
|||
|
|
### 5.2 Billing 套件
|
|||
|
|
|
|||
|
|
1. 幂等扣费:重复 `request_id` 不重复扣费。
|
|||
|
|
2. 冲突检测:`billing_conflict_rate_pct` 监测与告警。
|
|||
|
|
3. 对账一致性:usage 与 billing 差异 <= 0.1%。
|
|||
|
|
|
|||
|
|
### 5.3 兼容契约套件
|
|||
|
|
|
|||
|
|
1. Schema Gate:请求/响应字段与类型。
|
|||
|
|
2. Behavior Gate:stream/no-replay/错误码语义。
|
|||
|
|
3. Performance Gate:P95/P99/5xx/账务指标。
|
|||
|
|
|
|||
|
|
### 5.4 安全套件
|
|||
|
|
|
|||
|
|
1. query key 外拒内转边界。
|
|||
|
|
2. subapi 内网隔离与 mTLS。
|
|||
|
|
3. RLS/租户越权访问防护。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. Go 测试示例(最小可执行)
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
package billing_test
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"testing"
|
|||
|
|
"github.com/stretchr/testify/require"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func TestCharge_IdempotentByRequestID(t *testing.T) {
|
|||
|
|
svc := newTestBillingService(t)
|
|||
|
|
|
|||
|
|
reqID := "req-123"
|
|||
|
|
err1 := svc.Charge("u1", reqID, 100)
|
|||
|
|
err2 := svc.Charge("u1", reqID, 100)
|
|||
|
|
|
|||
|
|
require.NoError(t, err1)
|
|||
|
|
require.NoError(t, err2)
|
|||
|
|
|
|||
|
|
cnt, err := svc.CountTransactionsByRequestID(reqID)
|
|||
|
|
require.NoError(t, err)
|
|||
|
|
require.Equal(t, 1, cnt)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. CI 门禁流水线(Go版)
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
name: go-test-pipeline
|
|||
|
|
on:
|
|||
|
|
pull_request:
|
|||
|
|
branches: [main]
|
|||
|
|
push:
|
|||
|
|
branches: [main]
|
|||
|
|
|
|||
|
|
jobs:
|
|||
|
|
unit:
|
|||
|
|
runs-on: ubuntu-latest
|
|||
|
|
steps:
|
|||
|
|
- uses: actions/checkout@v4
|
|||
|
|
- uses: actions/setup-go@v5
|
|||
|
|
with:
|
|||
|
|
go-version: '1.21.x'
|
|||
|
|
- run: go test ./... -coverprofile=coverage.out
|
|||
|
|
- run: go tool cover -func=coverage.out
|
|||
|
|
|
|||
|
|
integration:
|
|||
|
|
runs-on: ubuntu-latest
|
|||
|
|
steps:
|
|||
|
|
- uses: actions/checkout@v4
|
|||
|
|
- uses: actions/setup-go@v5
|
|||
|
|
with:
|
|||
|
|
go-version: '1.21.x'
|
|||
|
|
- run: go test -tags=integration ./tests/integration/...
|
|||
|
|
|
|||
|
|
gate:
|
|||
|
|
runs-on: ubuntu-latest
|
|||
|
|
steps:
|
|||
|
|
- uses: actions/checkout@v4
|
|||
|
|
- uses: actions/setup-go@v5
|
|||
|
|
with:
|
|||
|
|
go-version: '1.21.x'
|
|||
|
|
- run: go test -tags=gate ./tests/contract/...
|
|||
|
|
- run: ./scripts/gate/perf_gate_check.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. 历史 Python 测试迁移映射
|
|||
|
|
|
|||
|
|
| 历史做法 | 对齐后做法 |
|
|||
|
|
|---|---|
|
|||
|
|
| `pytest` 单测 | `go test` + `testify` |
|
|||
|
|
| Python `AsyncClient` API 测试 | Go `httptest` + 集成容器 |
|
|||
|
|
| sqlite 内存库 | PostgreSQL 容器(与生产一致) |
|
|||
|
|
| Python 契约脚本 | Go 契约测试 + CI gate 标签 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. 实施排期(首周)
|
|||
|
|
|
|||
|
|
1. D1-D2:迁移 Router/Billing 单测到 Go 主链路。
|
|||
|
|
2. D3:补齐 integration(PostgreSQL/Redis)。
|
|||
|
|
3. D4:接入 gate 标签与性能门禁脚本。
|
|||
|
|
4. D5:提交覆盖率与门禁报告。
|
|||
|
|
|