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

6.1 KiB
Raw Blame History

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

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

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

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

// 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

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