关于 typescript-e2e-testing
typescript-e2e-testing 是指导端到端测试设置、编写、审查、运行、调试和优化的技能,面向使用 TypeScript 的项目团队。它按任务提供工作流,并强调真实基础设施、测试隔离和逐项排错。
主要功能
- 01按任务选择测试工作流
- 02提供 GWT 测试编写指导
- 03覆盖多种数据库与消息系统
- 04指导隔离、清理和断言
- 05提供失败排查与性能优化流程
适用场景
- 01为项目搭建 E2E 测试结构
- 02编写或审查端到端用例
- 03定位不稳定或失败的测试
- 04缩短测试套件运行时间
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bmad-labs/ skills --skill typescript-e2e-testing安装后在 Claude Code 中输入/typescript-e2e-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api/examples.mdknowledge.mdmocking.mdrules.mdtest-helper.mdreferences/common/best-practices.mddebugging.mdexamples.mdknowledge.mdnestjs-setup.mdrules.mdtest-case-creation-guide.mdreferences/kafka/docker-setup.mdexamples.mdisolation.mdknowledge.mdperformance.mdrules.mdtest-helper.mdreferences/mongodb/docker-setup.mdexamples.mdknowledge.mdrules.mdtest-helper.mdreferences/postgres/examples.mdknowledge.mdrules.mdtest-helper.mdreferences/redis/docker-setup.md详细介绍
E2E 测试技能
E2E 测试使用 Docker 提供的真实基础设施,从用户视角验证完整工作流。
工作流
如需全面的分步指导,请使用合适的工作流:
| 工作流 | 使用时机 |
|---|---|
| 设置 E2E 测试 | 为新项目或现有项目设置 E2E 基础设施 |
| 编写 E2E 测试 | 使用合适的 GWT 模式创建新的 E2E 测试用例 |
| 审查 E2E 测试 | 审查现有测试的质量和正确性 |
| 运行 E2E 测试 | 通过适当的验证执行测试 |
| 调试 E2E 测试 | 系统地修复失败的测试 |
| 优化 E2E 测试 | 提升测试套件的性能 |
工作流选择指南
重要:开始任何 E2E 测试任务之前,请先确定用户的意图并加载合适的工作流。
识别用户意图 → 选择工作流
| 用户说 / 想要 | 要加载的工作流 | 文件 |
|---|---|---|
| “设置 E2E 测试”、“配置 docker-compose”、“为项目添加 E2E”、“创建测试辅助工具” | 设置 | workflows/setup/workflow.md |
| “编写 E2E 测试”、“添加集成测试”、“测试这个端点”、“创建 e2e-spec” | 编写 | workflows/writing/workflow.md |
| “审查 E2E 测试”、“检查测试质量”、“审核测试”、“这个测试正确吗?” | 审查 | workflows/review/workflow.md |
| “运行 E2E 测试”、“执行测试”、“启动 Docker 并测试”、“检查测试是否通过” | 运行 | workflows/running/workflow.md |
| “修复 E2E 测试”、“调试测试”、“测试失败了”、“不稳定的测试”、“连接错误” | 调试 | workflows/debugging/workflow.md |
| “加快 E2E 测试”、“优化测试”、“测试运行很慢”、“缩短测试时间” | 优化 | workflows/optimize/workflow.md |
工作流执行规范
- 始终先加载工作流文件——采取行动前,完整阅读工作流
- 按顺序执行每个步骤——完成检查点后再继续
- 按指示加载知识文件——每个工作流都会指定要阅读哪些
references/文件 - 完成后验证是否符合要求——重新阅读相关参考文件,确保质量
重要:每个工作流都包含相关指示,要求在完成任务前后从 references/ 文件夹加载相关知识。
知识库结构
references/
├── common/ # Shared testing fundamentals
│ ├── knowledge.md # Core E2E concepts and test pyramid
│ ├── rules.md # Mandatory testing rules (GWT, timeouts, logging)
│ ├── best-practices.md # Test design and cleanup patterns
│ ├── test-case-creation-guide.md # GWT templates for all scenarios
│ ├── nestjs-setup.md # NestJS app bootstrap and Jest config
│ ├── debugging.md # VS Code config and log analysis
│ └── examples.md # Comprehensive examples by category
│
├── kafka/ # Kafka-specific testing
│ ├── knowledge.md # Why common approaches fail, architecture
│ ├── rules.md # Kafka-specific testing rules
│ ├── test-helper.md # KafkaTestHelper implementation
│ ├── docker-setup.md # Redpanda/Kafka Docker configs
│ ├── performance.md # Optimization techniques
│ ├── isolation.md # Pre-subscription pattern details
│ └── examples.md # Kafka test examples
│
├── postgres/ # PostgreSQL-specific testing
│ ├── knowledge.md # PostgreSQL testing concepts
│ ├── rules.md # Cleanup, transaction, assertion rules
│ ├── test-helper.md # PostgresTestHelper implementation
│ └── examples.md # CRUD, transaction, constraint examples
│
├── mongodb/ # MongoDB-specific testing
│ ├── knowledge.md # MongoDB testing concepts
│ ├── rules.md # Document cleanup and assertion rules
│ ├── test-helper.md # MongoDbTestHelper implementation
│ ├── docker-setup.md # Docker and Memory Server setup
│ └── examples.md # Document and aggregation examples
│
├── redis/ # Redis-specific testing
│ ├── knowledge.md # Redis testing concepts
│ ├── rules.md # TTL and pub/sub rules
│ ├── test-helper.md # RedisTestHelper implementation
│ ├── docker-setup.md # Docker configuration
│ └── examples.md # Cache, session, rate limit examples
│
└── api/ # API testing (REST, GraphQL, gRPC)
├── knowledge.md # API testing concepts
├── rules.md # Request/response assertion rules
├── test-helper.md # Auth and Supertest helpers
├── examples.md # REST, GraphQL, validation examples
└── mocking.md # MSW and Nock external API mocking
按任务分类的快速参考
提示:如需详细的分步指导,请使用上方的工作流部分。
设置新的 E2E 结构
工作流:设置 E2E 测试
- 阅读
references/common/knowledge.md——了解 E2E 基础知识 - 阅读
references/common/nestjs-setup.md——项目设置 - 根据需要阅读特定技术的
docker-setup.md文件
编写测试用例
工作流:编写 E2E 测试
- 必须:阅读
references/common/rules.md——GWT 模式、超时时间 - 阅读
references/common/test-case-creation-guide.md——模板 - 阅读特定技术的文件:
- Kafka:
references/kafka/knowledge.md→test-helper.md→isolation.md - PostgreSQL:
references/postgres/rules.md→test-helper.md - MongoDB:
references/mongodb/rules.md→test-helper.md - Redis:
references/redis/rules.md→test-helper.md - API:
references/api/rules.md→test-helper.md
- Kafka:
审查测试质量
工作流:审查 E2E 测试
- 阅读
references/common/rules.md——检查是否符合强制模式 - 阅读
references/common/best-practices.md——质量标准 - 阅读特定技术的
rules.md文件
运行 E2E 测试
工作流:运行 E2E 测试
- 确认 Docker 基础设施正在运行
- 按顺序运行测试:
npm run test:e2e > /tmp/e2e-${E2E_SESSION}-output.log 2>&1 - 如果测试失败,遵循失败处理流程
调试失败的测试
工作流:调试 E2E 测试
- 阅读
references/common/debugging.md - 创建
/tmp/e2e-${E2E_SESSION}-failures.md跟踪文件 - 一次修复 ONE 个测试
优化测试性能
工作流:优化 E2E 测试
- 阅读
references/common/best-practices.md——性能模式 - 阅读
references/kafka/performance.md,了解 Kafka 测试 - 修改前先测量基准性能
示例
- 阅读
references/common/examples.md,了解通用模式 - 阅读特定技术的
examples.md,了解详细场景
核心原则
0. 上下文效率(输出到临时文件)
始终将 E2E 测试输出重定向到临时文件,而非控制台。E2E 输出内容冗长,会占用过多 Agent 上下文。
重要:仅将输出重定向到临时文件(不输出到控制台)。使用唯一的会话 ID,避免冲突。
# Generate unique session ID at start of debugging session
export E2E_SESSION=$(date +%s)-$$
# Standard pattern - redirect to file only (no console output)
npm run test:e2e > /tmp/e2e-${E2E_SESSION}-output.log 2>&1
# Read summary only (last 50 lines)
tail -50 /tmp/e2e-${E2E_SESSION}-output.log
# Get failure details
grep -B 2 -A 15 "FAIL\|✕" /tmp/e2e-${E2E_SESSION}-output.log
# Cleanup when done
rm -f /tmp/e2e-${E2E_SESSION}-*.log /tmp/e2e-${E2E_SESSION}-*.md
临时文件(${E2E_SESSION} 对每个 Agent 均为唯一值):
/tmp/e2e-${E2E_SESSION}-output.log- 完整测试输出/tmp/e2e-${E2E_SESSION}-failures.log- 筛选后的失败输出/tmp/e2e-${E2E_SESSION}-failures.md- 逐个修复的跟踪文件/tmp/e2e-${E2E_SESSION}-debug.log- 调试运行/tmp/e2e-${E2E_SESSION}-verify.log- 验证运行
1. 真实基础设施
通过 Docker 对实际服务进行测试。E2E 测试绝不模拟数据库或消息代理。
2. GWT 模式(强制)
所有 E2E 测试都必须遵循 Given-When-Then:
it('should create user and return 201', async () => {
// GIVEN: Valid user data
const userData = { email: '[email protected]', name: 'Test' };
// WHEN: Creating user
const response = await request(httpServer)
.post('/users')
.send(userData)
.expect(201);
// THEN: User created with correct data
expect(response.body.data.email).toBe('[email protected]');
});
3. 测试隔离
每项测试都必须相互独立:
- 在
beforeEach中清理数据库状态 - 使用唯一标识符(消费者组、主题)
- 等待异步操作完成
4. 明确的断言
断言精确值,而不只是断言其存在:
// WRONG
expect(response.body.data).toBeDefined();
// CORRECT
expect(response.body).toMatchObject({
code: 'SUCCESS',
data: { email: '[email protected]', name: 'Test' }
});
项目结构
project-root/
├── src/
├── test/
│ ├── e2e/
│ │ ├── feature.e2e-spec.ts
│ │ ├── setup.ts
│ │ └── helpers/
│ │ ├── test-app.helper.ts
│ │ ├── postgres.helper.ts
│ │ ├── mongodb.helper.ts
│ │ ├── redis.helper.ts
│ │ └── kafka.helper.ts
│ └── jest-e2e.config.ts
├── docker-compose.e2e.yml
├── .env.e2e
└── package.json
Jest 核心配置
// test/jest-e2e.config.ts
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/*.e2e-spec.ts'],
testTimeout: 25000,
maxWorkers: 1, // CRITICAL: Sequential execution
clearMocks: true,
forceExit: true,
detectOpenHandles: true,
};
特定技术的超时设置
| 技术 | 等待时间 | 策略 |
|---|---|---|
| Kafka | 最长 10-20s(轮询) | 每隔 50ms 进行智能轮询 |
| PostgreSQL | <1s | 直接查询 |
| MongoDB | <1s | 直接查询 |
| Redis | <100ms | 内存操作 |
| 外部 API | 1-5s | 网络延迟 |
失败处理流程
关键:一次修复 ONE 个测试。修复期间绝不反复运行整个测试套件。
E2E 测试失败时:
- 初始化会话(开始时执行一次):
export E2E_SESSION=$(date +%s)-$$ - 创建跟踪文件:
/tmp/e2e-${E2E_SESSION}-failures.md,列出所有失败的测试 - 选择 ONE 个失败的测试——仅处理这个测试
- 仅运行该测试(绝不运行整个测试套件):
npm run test:e2e -- -t "test name" > /tmp/e2e-${E2E_SESSION}-debug.log 2>&1 tail -50 /tmp/e2e-${E2E_SESSION}-debug.log - 修复问题——分析错误并进行针对性修复
- 验证修复——运行同一测试 3-5 次:
for i in {1..5}; do npm run test:e2e -- -t "test name" > /tmp/e2e-${E2E_SESSION}-run$i.log 2>&1 && echo "Run $i: PASS" || echo "Run $i: FAIL"; done - 在跟踪文件中将其标记为 FIXED
- 处理下一个失败的测试——重复步骤 3-7
- 只有在所有单项测试都通过后,才运行一次完整测试套件
- 清理:
rm -f /tmp/e2e-${E2E_SESSION}-*.log /tmp/e2e-${E2E_SESSION}-*.md
原因:运行整个测试套件会浪费时间和上下文。每个失败的测试都会使输出内容膨胀,增加调试难度。
常见模式
数据库清理(PostgreSQL/MongoDB)
beforeEach(async () => {
await new Promise(r => setTimeout(r, 500)); // Wait for in-flight
await repository.clear(); // PostgreSQL
// OR
await model.deleteMany({}); // MongoDB
});
Kafka 测试辅助工具模式
// Use pre-subscription + buffer clearing (NOT fromBeginning: true)
const kafkaHelper = new KafkaTestHelper();
await kafkaHelper.subscribeToTopic(outputTopic, false);
// In beforeEach: kafkaHelper.clearMessages(outputTopic);
Redis 清理
beforeEach(async () => {
await redis.flushdb();
});
外部 API 模拟(MSW)
mockServer.use(
http.post('https://api.external.com/endpoint', () => {
return HttpResponse.json({ status: 'success' });
})
);
异步事件验证(Kafka)
// Use smart polling instead of fixed waits
await kafkaHelper.publishEvent(inputTopic, event, event.id);
const messages = await kafkaHelper.waitForMessages(outputTopic, 1, 20000);
expect(messages[0].value).toMatchObject({ id: event.id });
调试命令
所有命令都仅将输出重定向到临时文件(不输出到控制台)。
# Initialize session (once at start)
export E2E_SESSION=$(date +%s)-$$
# Run specific test (no console output)
npm run test:e2e -- -t "should create user" > /tmp/e2e-${E2E_SESSION}-output.log 2>&1 && tail -50 /tmp/e2e-${E2E_SESSION}-output.log
# Run specific file
npm run test:e2e -- test/e2e/user.e2e-spec.ts > /tmp/e2e-${E2E_SESSION}-output.log 2>&1 && tail -50 /tmp/e2e-${E2E_SESSION}-output.log
# Run full suite
npm run test:e2e > /tmp/e2e-${E2E_SESSION}-output.log 2>&1 && tail -50 /tmp/e2e-${E2E_SESSION}-output.log
# Get failure details from last run
grep -B 2 -A 15 "FAIL\|✕" /tmp/e2e-${E2E_SESSION}-output.log
# Debug with breakpoints (requires console for interactive debugging)
node --inspect-brk node_modules/.bin/jest --config test/jest-e2e.config.ts --runInBand
# View application logs (limited)
tail -100 logs/e2e-test.log
grep -i error logs/e2e-test.log | tail -50
# Cleanup session files
rm -f /tmp/e2e-${E2E_SESSION}-*.log /tmp/e2e-${E2E_SESSION}-*.md
应避免的反模式
- 多个 WHEN 操作 - 拆分为多个独立测试
- 条件断言 - 创建确定性的测试用例
- 测试间共享状态 - 在 beforeEach 中清理
- 模拟数据库 - 使用真实连接
- 跳过清理 - 始终在测试前和测试后清理
- 一次修复多个测试 - 每次只修复一个
- 通用断言 - 断言具体值
- 对 Kafka 使用 fromBeginning: true - 先订阅,再清空缓冲区