Files
sub2api/.github/workflows/ci.yml
yangjianbo bb5a5dd65e test: 完善自动化测试体系(7个模块,73个任务)
系统性地修复、补充和强化项目的自动化测试能力:

1. 测试基础设施修复
   - 修复 stubConcurrencyCache 缺失方法和构造函数参数不匹配
   - 创建 testutil 共享包(stubs.go, fixtures.go, httptest.go)
   - 为所有 Stub 添加编译期接口断言

2. 中间件测试补充
   - 新增 JWT 认证中间件测试(有效/过期/篡改/缺失 Token)
   - 补充 rate_limiter 和 recovery 中间件测试场景

3. 网关核心路径测试
   - 新增账户选择、等待队列、流式响应、并发控制、计费、Claude Code 检测测试
   - 覆盖负载均衡、粘性会话、SSE 转发、槽位管理等关键逻辑

4. 前端测试体系(11个新测试文件,163个测试用例)
   - Pinia stores: auth, app, subscriptions
   - API client: 请求拦截器、响应拦截器、401 刷新
   - Router guards: 认证重定向、管理员权限、简易模式限制
   - Composables: useForm, useTableLoader, useClipboard
   - Components: LoginForm, ApiKeyCreate, Dashboard

5. CI/CD 流水线重构
   - 重构 backend-ci.yml 为统一的 ci.yml
   - 前后端 4 个并行 Job + Postgres/Redis services
   - Race 检测、覆盖率收集与门禁、Docker 构建验证

6. E2E 自动化测试
   - e2e-test.sh 自动化脚本(Docker 启动→健康检查→测试→清理)
   - 用户注册→登录→API Key→网关调用完整链路测试
   - Mock 模式和 API Key 脱敏支持

7. 修复预存问题
   - tlsfingerprint dialer_test.go 缺失 build tag 导致集成测试编译冲突

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:05:39 +08:00

180 lines
5.8 KiB
YAML
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.

name: CI
on:
push:
pull_request:
permissions:
contents: read
jobs:
# ==========================================================================
# 后端测试(与前端并行运行)
# ==========================================================================
backend-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: sub2api_test
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U test"
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: backend/go.mod
check-latest: false
cache: true
- name: 验证 Go 版本
run: go version | grep -q 'go1.25.7'
- name: 单元测试
working-directory: backend
run: make test-unit
- name: 集成测试
working-directory: backend
env:
DATABASE_URL: postgres://test:test@localhost:5432/sub2api_test?sslmode=disable
REDIS_URL: redis://localhost:6379/0
run: make test-integration
- name: Race 检测
working-directory: backend
run: go test -tags=unit -race -count=1 ./...
- name: 覆盖率收集
working-directory: backend
run: |
go test -tags=unit -coverprofile=coverage.out -count=1 ./...
echo "## 后端测试覆盖率" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
go tool cover -func=coverage.out | tail -1 >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: 覆盖率门禁≥8%
working-directory: backend
run: |
COVERAGE=$(go tool cover -func=coverage.out | tail -1 | awk '{print $3}' | sed 's/%//')
echo "当前覆盖率: ${COVERAGE}%"
if [ "$(echo "$COVERAGE < 8" | bc -l)" -eq 1 ]; then
echo "::error::后端覆盖率 ${COVERAGE}% 低于门禁值 8%"
exit 1
fi
# ==========================================================================
# 后端代码检查
# ==========================================================================
golangci-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: backend/go.mod
check-latest: false
cache: true
- name: 验证 Go 版本
run: go version | grep -q 'go1.25.7'
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.7
args: --timeout=5m
working-directory: backend
# ==========================================================================
# 前端测试(与后端并行运行)
# ==========================================================================
frontend-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: 安装 Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
cache-dependency-path: frontend/pnpm-lock.yaml
- name: 安装依赖
working-directory: frontend
run: pnpm install --frozen-lockfile
- name: 类型检查
working-directory: frontend
run: pnpm run typecheck
- name: Lint 检查
working-directory: frontend
run: pnpm run lint:check
- name: 单元测试
working-directory: frontend
run: pnpm run test:run
- name: 覆盖率收集
working-directory: frontend
run: |
pnpm run test:coverage -- --exclude '**/integration/**' || true
echo "## 前端测试覆盖率" >> $GITHUB_STEP_SUMMARY
if [ -f coverage/coverage-final.json ]; then
echo "覆盖率报告已生成" >> $GITHUB_STEP_SUMMARY
fi
- name: 覆盖率门禁≥20%
working-directory: frontend
run: |
if [ ! -f coverage/coverage-final.json ]; then
echo "::warning::覆盖率报告未生成,跳过门禁检查"
exit 0
fi
# 使用 node 解析覆盖率 JSON
COVERAGE=$(node -e "
const data = require('./coverage/coverage-final.json');
let totalStatements = 0, coveredStatements = 0;
for (const file of Object.values(data)) {
const stmts = file.s;
totalStatements += Object.keys(stmts).length;
coveredStatements += Object.values(stmts).filter(v => v > 0).length;
}
const pct = totalStatements > 0 ? (coveredStatements / totalStatements * 100) : 0;
console.log(pct.toFixed(1));
")
echo "当前前端覆盖率: ${COVERAGE}%"
if [ "$(echo "$COVERAGE < 20" | bc -l 2>/dev/null || node -e "console.log($COVERAGE < 20 ? 1 : 0)")" = "1" ]; then
echo "::warning::前端覆盖率 ${COVERAGE}% 低于门禁值 20%(当前为警告,不阻塞)"
fi
# ==========================================================================
# Docker 构建验证
# ==========================================================================
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Docker 构建验证
run: docker build -t aicodex2api:ci-test .