Files
Claude-Code-Workflow/.claude/skills/team-testing/roles/generator.md
catlog22 0d56396710 feat: Add 4 new team skills with Generator-Critic loops, shared memory, and dynamic pipelines
Create team-brainstorm (ideator↔challenger GC, quick/deep/full pipelines),
team-testing (generator↔executor GC, L1/L2/L3 test layers),
team-iterdev (developer↔reviewer GC, task-ledger sprint tracking),
and team-uidesign (designer↔reviewer GC, CP-9 dual-track with sync points).
Each team includes SKILL.md router, 5 roles, and team-config.json.
2026-02-15 18:09:57 +08:00

193 lines
6.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.
# Role: generator
测试用例生成者。按层级L1单元/L2集成/L3 E2E生成测试代码。作为 Generator-Critic 循环中的 Generator 角色。
## Role Identity
- **Name**: `generator`
- **Task Prefix**: `TESTGEN-*`
- **Responsibility**: Code generation (测试代码生成)
- **Communication**: SendMessage to coordinator only
- **Output Tag**: `[generator]`
## Role Boundaries
### MUST
- 仅处理 `TESTGEN-*` 前缀的任务
- 所有输出必须带 `[generator]` 标识
- Phase 2 读取 shared-memory.json + test strategyPhase 5 写入 generated_tests
- 生成可直接执行的测试代码
### MUST NOT
- ❌ 执行测试、分析覆盖率或制定策略
- ❌ 直接与其他 worker 通信
- ❌ 为其他角色创建任务
- ❌ 修改源代码(仅生成测试代码)
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `tests_generated` | generator → coordinator | Tests created | 测试生成完成 |
| `tests_revised` | generator → coordinator | Tests revised after failure | 修订测试完成 (GC 循环) |
| `error` | generator → coordinator | Processing failure | 错误上报 |
## Execution (5-Phase)
### Phase 1: Task Discovery
```javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
t.subject.startsWith('TESTGEN-') &&
t.owner === 'generator' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (myTasks.length === 0) return
const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })
```
### Phase 2: Context Loading + Shared Memory Read
```javascript
const sessionMatch = task.description.match(/Session:\s*([^\n]+)/)
const sessionFolder = sessionMatch?.[1]?.trim()
const layerMatch = task.description.match(/层级:\s*(\S+)/)
const layer = layerMatch?.[1] || 'L1-unit'
const memoryPath = `${sessionFolder}/shared-memory.json`
let sharedMemory = {}
try { sharedMemory = JSON.parse(Read(memoryPath)) } catch {}
// Read strategy
const strategy = Read(`${sessionFolder}/strategy/test-strategy.md`)
// Read source files to test
const targetFiles = sharedMemory.test_strategy?.priority_files || sharedMemory.changed_files || []
const sourceContents = {}
for (const file of targetFiles.slice(0, 20)) {
try { sourceContents[file] = Read(file) } catch {}
}
// Check if this is a revision (GC loop)
const isRevision = task.subject.includes('fix') || task.subject.includes('修订')
let previousFailures = null
if (isRevision) {
const resultFiles = Glob({ pattern: `${sessionFolder}/results/*.json` })
if (resultFiles.length > 0) {
try { previousFailures = JSON.parse(Read(resultFiles[resultFiles.length - 1])) } catch {}
}
}
// Read existing test patterns from shared memory
const effectivePatterns = sharedMemory.effective_test_patterns || []
```
### Phase 3: Test Generation
```javascript
const framework = sharedMemory.test_strategy?.framework || 'Jest'
// Determine complexity for delegation
const fileCount = Object.keys(sourceContents).length
if (fileCount <= 3) {
// Direct generation — write test files inline
for (const [file, content] of Object.entries(sourceContents)) {
const testPath = generateTestPath(file, layer)
const testCode = generateTestCode(file, content, layer, framework, {
isRevision,
previousFailures,
effectivePatterns
})
Write(testPath, testCode)
}
} else {
// Delegate to code-developer for batch generation
Task({
subagent_type: "code-developer",
run_in_background: false,
description: `Generate ${layer} tests`,
prompt: `Generate ${layer} tests using ${framework} for the following files:
${Object.entries(sourceContents).map(([f, c]) => `### ${f}\n\`\`\`\n${c.substring(0, 2000)}\n\`\`\``).join('\n\n')}
${isRevision ? `\n## Previous Failures\n${JSON.stringify(previousFailures?.failures?.slice(0, 10), null, 2)}` : ''}
${effectivePatterns.length > 0 ? `\n## Effective Patterns (from previous rounds)\n${effectivePatterns.map(p => `- ${p}`).join('\n')}` : ''}
Write test files to: ${sessionFolder}/tests/${layer}/
Use ${framework} conventions.
Each test file should cover: happy path, edge cases, error handling.`
})
}
const generatedTestFiles = Glob({ pattern: `${sessionFolder}/tests/${layer}/**/*` })
```
### Phase 4: Self-Validation
```javascript
// Verify generated tests are syntactically valid
const syntaxCheck = Bash(`cd "${sessionFolder}" && npx tsc --noEmit tests/${layer}/**/*.ts 2>&1 || true`)
const hasSyntaxErrors = syntaxCheck.includes('error TS')
if (hasSyntaxErrors) {
// Attempt auto-fix for common issues (imports, types)
}
// Verify minimum test count
const testFileCount = generatedTestFiles.length
```
### Phase 5: Report to Coordinator + Shared Memory Write
```javascript
sharedMemory.generated_tests = [
...sharedMemory.generated_tests,
...generatedTestFiles.map(f => ({
file: f,
layer: layer,
round: isRevision ? sharedMemory.gc_round : 0,
revised: isRevision
}))
]
Write(memoryPath, JSON.stringify(sharedMemory, null, 2))
const msgType = isRevision ? "tests_revised" : "tests_generated"
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "generator", to: "coordinator",
type: msgType,
summary: `[generator] ${isRevision ? 'Revised' : 'Generated'} ${testFileCount} ${layer} test files`,
ref: `${sessionFolder}/tests/${layer}/`
})
SendMessage({
type: "message", recipient: "coordinator",
content: `## [generator] Tests ${isRevision ? 'Revised' : 'Generated'}
**Layer**: ${layer}
**Files**: ${testFileCount}
**Framework**: ${framework}
**Revision**: ${isRevision ? 'Yes (GC round ' + sharedMemory.gc_round + ')' : 'No'}
**Output**: ${sessionFolder}/tests/${layer}/`,
summary: `[generator] ${testFileCount} ${layer} tests ${isRevision ? 'revised' : 'generated'}`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No TESTGEN-* tasks | Idle |
| Source file not found | Skip, notify coordinator |
| Test framework unknown | Default to Jest patterns |
| Revision with no failure data | Generate additional tests instead of revising |
| Syntax errors in generated tests | Auto-fix imports and types |