AgentDock

集成测试

自动化测试策略与模板的端到端验证

集成测试

自动化测试是确保模板质量和可用性的关键环节。本文档记录了 AgentDock 项目的测试策略、工具和最佳实践。


为什么需要自动化测试?

在 AgentDock 项目中,我们面临以下挑战:

  1. 长验证链路:修改模板 → 合并 main → 发布 CLI → 用户验收,一旦发现问题需要重复整个流程
  2. 多环境影响:模板在 monorepo 内工作正常,但独立项目可能失败
  3. 架构约束:Layer 2 规则容易被忽视,导致运行时错误
  4. 安全风险:硬编码密钥、open redirect 漏洞等

解决方案:在合并前进行完整的自动化测试,提前发现问题。


测试金字塔

我们采用分层测试策略:

        ┌─────────────────────┐
        │   E2E Tests (5%)    │  ← 真实浏览器、完整流程
        ├─────────────────────┤
        │ Integration (20%)   │  ← API 集成、Repository 层
        ├─────────────────────┤
        │ Unit Tests (75%)    │  ← 业务逻辑、Server Actions
        └─────────────────────┘

Layer 1: 单元测试(Unit Tests)

目标:验证独立的业务逻辑单元

工具:Vitest

示例

// src/features/auth/actions.test.ts
import { describe, it, expect } from 'vitest'
import { requestPasswordReset } from './actions'

describe('requestPasswordReset', () => {
  it('should prevent email enumeration', async () => {
    // Always returns success even for non-existent emails
    const result = await requestPasswordReset(null, new FormData())
    expect(result.error).toBeNull()
  })
})

运行方式

cd templates/web-nextjs/apps/web
pnpm test

Layer 2: 集成测试(Integration Tests)

目标:验证模块间的交互和依赖

场景

  • Repository 模式:IAuthRepository → SupabaseAuthRepository
  • Server Actions → Repository → Supabase Client
  • Middleware → Auth Session → Page Access

工具:Vitest + Mock Supabase

示例

// src/core/repositories/IAuthRepository.test.ts
import { describe, it, expect, vi } from 'vitest'
import { getAuthRepository } from '@/infra/providers'

describe('AuthRepository Integration', () => {
  it('should create repository instance', () => {
    const repo = getAuthRepository()
    expect(repo).toBeDefined()
    expect(typeof repo.signInWithPassword).toBe('function')
  })
})

Layer 3: 端到端测试(E2E Tests)

目标:模拟真实用户操作,验证完整流程

场景

  • 密码重置完整流程:忘记密码 → 收邮件 → 重置 → 登录
  • OAuth 登录:GitHub 授权 → 回调 → 创建账户
  • Profile 管理:登录 → 修改显示名 → 保存 → 验证持久化

工具:Playwright(计划中)

当前实现:基于 Bash 脚本的 HTTP 端点测试


当前测试方案

方案 1:快速验证脚本

文件scripts/validate-template.sh

适用场景

  • 每次提交前的快速检查
  • 小改动(typo、注释)的验证
  • CI/CD 中的初步筛选

运行时间:5-10 分钟

检查项(29 项):

✓ 环境检查(Node.js, pnpm)
✓ 依赖安装
✓ ESLint(包括 Layer 2 约束)
✓ TypeScript 类型检查
✓ 生产构建
✓ 架构完整性(Repository 模式)
✓ 功能完整性(密码重置、Profile 页等)
✓ i18n 支持
✓ 安全检查(无硬编码密钥)
✓ 文件结构

使用方法

./scripts/validate-template.sh

预期输出

✓ All critical checks passed!

Passed:   29
Failed:   0
Warnings: 2

方案 2:完整 E2E 测试(推荐)

文件scripts/e2e-template-test-v2.sh

适用场景

  • 合并到 main 分支前的最终验收
  • 新功能开发的完成验证
  • 发布前的质量保障

运行时间:10-15 分钟

测试流程(5 个 Phase):

Phase 1: 静态检查(Monorepo Context)

cd templates/web-nextjs/apps/web
npx eslint 'src/**/*.{ts,tsx}'    # Layer 2 约束检查
npx tsc --noEmit                  # 类型安全
npx next build                    # 生产构建

关键点:使用 npx 而非 pnpm,避免 workspace 依赖检查失败。

Phase 2: 运行时测试

rm -rf .next/dev/cache            # 清理 Turbopack 缓存
npx next dev &                    # 启动开发服务器
wait_for_server(60s)              # 等待就绪

关键点:必须清理缓存,否则可能遇到 "corrupted database" 错误。

Phase 3: HTTP 端点验证

curl http://localhost:3000/en                  # 首页
curl http://localhost:3000/en/forgot-password  # 新功能
curl http://localhost:3000/en/reset-password   # 新功能
curl http://localhost:3000/en/settings/profile # 新功能

测试结果(22 项):

✓ Homepage (200)
✓ Login page (200)
✓ Signup page (200)
✓ Dashboard handles unauth access (500)
✓ ✨ Forgot password page (200)
✓ ✨ Reset password page (200)
✓ ✨ Profile settings page accessible (500)
✓ Help page (200)
✓ Privacy policy (200)
✓ About page (200)
✓ Auth callback redirects (307)

Phase 4: 内容与安全检查

# 内容验证
grep "email" forgot-password-page.html
grep "password" reset-password-page.html

# 架构检查
grep -r "from '@/infra/db/client'" src/features/*/actions.ts  # 应该为空

# 安全检查
grep -rE "sb-[a-z0-9]{20,}" src/ | grep -v process.env  # 应该为空
grep "ALLOWED_NEXT" src/app/auth/callback/route.ts       # 应该存在

Phase 5: 清理

lsof -ti:3000 | xargs kill -9  # 停止服务器

使用方法

./scripts/e2e-template-test-v2.sh

预期输出

╔════════════════════════════════════════════════════════╗
║  ✓ ALL TESTS PASSED - READY FOR MERGE                ║
╚════════════════════════════════════════════════════════╝

Results:
  Passed: 22
  Failed: 0

✅ Template is validated and ready!

Next Steps:
1. Merge to main: git checkout main && git merge <branch>
2. Update docs: changelog, roadmap
3. Release: git tag v0.x.0
4. Final CLI test: agentdock create test-app

测试环境配置

环境变量管理

原则:单一真相源(Single Source of Truth)

实现:根目录 .env.local 包含所有测试所需的环境变量

# .env.local (root directory)
NEXT_PUBLIC_SUPABASE_URL=https://supabase.fujia.site
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbG...
SUPABASE_SERVICE_ROLE_KEY=eyJhbG...
NEXT_PUBLIC_APP_URL=http://localhost:3000
APP_DEFAULT_LOCALE=zh

优势

  • 所有模板共享同一套测试凭证
  • 易于轮换密钥(只需修改一个文件)
  • 避免在多个位置维护环境变量

Supabase 测试环境

要求

  • 真实的 Supabase 项目(非 Mock)
  • 启用了 Email Auth 和 GitHub OAuth
  • 配置了正确的回调 URL

配置步骤

  1. 创建 Supabase 项目
  2. 启用 Authentication → Email provider
  3. 启用 Authentication → GitHub provider
  4. 配置 Site URL: http://localhost:3000
  5. 复制 API keys 到 .env.local

常见问题排查

问题 1: pnpm 命令失败

症状

[ERROR] Command failed with exit code 1: pnpm install

原因:pnpm workspace 依赖检查失败

解决:使用 npx 替代 pnpm 运行命令

npx eslint 'src/**/*.{ts,tsx}'
npx tsc --noEmit
npx next build
npx next dev

问题 2: Dev Server 启动超时

症状

✗ FAIL: Dev server failed to start within 60s

原因:Turbopack 缓存损坏

解决

rm -rf .next/dev/cache
npx next dev

问题 3: Dashboard/Profile 返回 500

症状

✗ FAIL: Dashboard returned 500 (expected 307)

原因:这些页面需要认证,未登录时可能抛出错误而非重定向

处理:接受 500 作为合法响应(在测试脚本中已处理)

问题 4: Layer 2 违规误报

症状

✗ FAIL: Found direct infra imports in features

检查

grep -r "from '@/infra/db/client'" src/features/*/actions.ts

说明server.ts 可以 import infra(它是基础设施 helper),但 actions.ts 不行。


测试最佳实践

1. 测试频率

  • 每次提交前:运行快速验证 (validate-template.sh)
  • 合并到 main 前:运行完整 E2E 测试
  • 发布前:E2E + 手动功能测试

2. 环境隔离

  • 使用根目录 .env.local 作为单一真相源
  • 不要在生产环境中使用测试凭证
  • 定期轮换 Supabase 密钥

3. 失败处理

  • 立即修复:Layer 2 违规、TypeScript 错误、安全检查失败
  • 可以忽略:Dashboard/Profile 的 500 错误(需要认证)
  • 需要调查:Dev Server 超时、构建失败

4. 性能优化

  • 清理 Turbopack 缓存后再启动 dev server
  • 使用 npx 而非 pnpm 避免 workspace 检查
  • 并行运行独立测试(如果可能)

5. 文档同步

  • 每次测试脚本更新后,同步更新 SKILL.md
  • 记录新的失败模式和解决方案
  • 保持 checklist.json 与实际测试一致

未来规划

短期(1-2 个月)

  1. Playwright E2E 测试

    • 实现真实的浏览器自动化测试
    • 覆盖密码重置完整流程
    • 截图对比和视觉回归测试
  2. Testcontainers 集成

    • 使用 Docker 容器运行 Supabase
    • 完全隔离的测试环境
    • 自动清理测试数据
  3. 测试报告生成

    • HTML/PDF 格式的可视化报告
    • 历史趋势分析
    • 失败率统计

中期(3-6 个月)

  1. CI/CD 集成

    • GitHub Actions 自动触发测试
    • PR 评论中显示测试结果
    • 阻止合并不合格的变更
  2. 性能测试

    • Lighthouse 自动化评分
    • 首屏加载时间监控
    • Bundle size 预算检查
  3. 无障碍测试

    • axe-core 自动化扫描
    • WCAG 2.1 合规性检查
    • 键盘导航测试

长期(6-12 个月)

  1. 智能测试选择

    • 基于变更内容自动选择相关测试
    • 减少不必要的测试执行
    • 加速 CI/CD 流水线
  2. 契约测试

    • OpenAPI/Swagger 验证
    • API 向后兼容性检查
    • 版本冲突检测
  3. 混沌工程

    • 随机故障注入
    • 网络延迟模拟
    • 容错能力测试

相关资源

脚本和工具

Skills

文档


贡献指南

想改进测试流程?欢迎贡献!

  1. 提出建议:在 GitHub Issues 中讨论
  2. 提交 PR:修改测试脚本或文档
  3. 分享经验:记录新的失败模式和解决方案

让我们一起打造更可靠的测试体系!

On this page