Install
$ agentstack add skill-nihao555-hub-claude-code-agent-skills-testing-quality-assurance-engineer Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Dangerous shell/eval execution.
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Testing & Quality Assurance Engineer
使用此技能当你需要进行测试策略设计、编写测试用例、建立质量门禁系统、或提升代码质量和测试覆盖率。
目标
产出完整的测试和质量保证方案,包括单元测试、集成测试、E2E 测试策略、测试覆盖率分析和质量门禁系统。
核心能力
1. 单元测试最佳实践
// 基于 Claude Code的测试模式
describe('TaskManager', () => {
let taskManager: TaskManager
let mockState: MockState
beforeEach(() => {
mockState = createMockState()
taskManager = new TaskManager(mockState)
})
afterEach(() => {
jest.restoreAllMocks()
})
describe('createTask', () => {
it('should create task with unique id', async () => {
// Arrange
const taskType = 'local_bash'
const description = 'Test task'
// Act
const task = await taskManager.createTask(taskType, description)
// Assert
expect(task.id).toMatch(/^[a-z][0-9a-z]{8}$/)
expect(task.type).toBe(taskType)
expect(task.status).toBe('pending')
})
it('should emit task:created event', async () => {
// Arrange
const eventHandler = jest.fn()
taskManager.on('task:created', eventHandler)
// Act
await taskManager.createTask('local_bash', 'Test')
// Assert
expect(eventHandler).toHaveBeenCalledTimes(1)
expect(eventHandler).toHaveBeenCalledWith(
expect.objectContaining({
type: 'local_bash',
status: 'pending'
})
)
})
it('should handle concurrent task creation', async () => {
// Arrange
const tasks = await Promise.all(
Array.from({ length: 10 }).map(() =>
taskManager.createTask('local_bash', 'Concurrent task')
)
)
// Assert - all IDs should be unique
const ids = tasks.map(t => t.id)
expect(new Set(ids).size).toBe(tasks.length)
})
})
})
2. 集成测试模式
// MCP 服务器集成测试
describe('MCP Integration', () => {
let mcpServer: MCPServer
let testClient: MCPClient
beforeAll(async () => {
// 启动真实的 MCP 服务器
mcpServer = await startTestMCPServer({
port: findAvailablePort()
})
// 连接到服务器
testClient = await connectMCPClient(mcpServer.url)
}, 30000) // 增加超时时间
afterAll(async () => {
// 清理资源
await testClient.disconnect()
await mcpServer.shutdown()
})
it('should list available tools', async () => {
// Act
const tools = await testClient.listTools()
// Assert
expect(tools).toHaveLength(expectedToolCount)
expect(tools.map(t => t.name)).toEqual([
'file_read',
'file_write',
'bash',
// ... expected tools
])
})
it('should execute tool and return result', async () => {
// Act
const result = await testClient.callTool('bash', {
command: 'echo "Hello World"'
})
// Assert
expect(result.content).toContain('Hello World')
expect(result.exitCode).toBe(0)
}, 10000)
})
3. E2E 测试框架
// Puppeteer/Playwright E2E测试
describe('Agent E2E Flow', () => {
let browser: Browser
let page: Page
beforeAll(async () => {
browser = await puppeteer.launch({
headless: process.env.CI ? true : false,
slowMo: 50 // CI 环境下加速
})
})
afterAll(async () => {
await browser.close()
})
beforeEach(async () => {
page = await browser.newPage()
// 设置视口
await page.setViewport({ width: 1280, height: 720 })
// 导航到应用
await page.goto('http://localhost:3000', {
waitUntil: 'networkidle0'
})
})
afterEach(async () => {
await page.close()
})
it('should complete full conversation flow', async () => {
// Step 1: 输入用户消息
await page.type('[data-testid="chat-input"]', 'Hello, can you help me?')
await page.click('[data-testid="send-button"]')
// Step 2: 等待 Agent 响应
await page.waitForSelector('[data-testid="assistant-message"]', {
timeout: 30000
})
// Step 3: 验证响应显示
const messages = await page.$$('[data-testid="message"]')
expect(messages.length).toBe(2) // 用户 + 助手
// Step 4: 截图对比(视觉回归测试)
const screenshot = await page.screenshot()
expect(screenshot).toMatchImageSnapshot({
customSnapshotsDir: '__snapshots__/e2e'
})
}, 60000)
it('should handle tool execution visualization', async () => {
// 发送需要执行工具的消息
await page.type('[data-testid="chat-input"]', 'List files in current directory')
await page.click('[data-testid="send-button"]')
// 等待工具执行 UI
await page.waitForSelector('[data-testid="tool-execution"]', {
timeout: 30000
})
// 验证工具执行进度显示
const progressBars = await page.$$('[data-testid="progress-bar"]')
expect(progressBars.length).toBeGreaterThan(0)
// 等待完成
await page.waitForSelector('[data-testid="tool-result"]', {
timeout: 30000
})
// 验证结果显示
const result = await page.$eval(
'[data-testid="tool-result"]',
el => el.textContent
)
expect(result).toBeTruthy()
}, 60000)
})
4. 测试覆盖率分析
interface CoverageReport {
total: {
statements: number
branches: number
functions: number
lines: number
}
covered: {
statements: number
branches: number
functions: number
lines: number
}
coverage: {
statements: number // percentage
branches: number
functions: number
lines: number
}
files: Array
}
function analyzeCoverage(report: CoverageReport): CoverageAnalysis {
const gaps: string[] = []
// 识别覆盖率低的文件
for (const file of report.files) {
if (file.coverage 0) {
recommendations.push('Add tests for uncovered files')
}
const criticalFiles = gaps.filter(g =>
g.includes('src/core/') || g.includes('src/utils/')
)
if (criticalFiles.length > 0) {
recommendations.push('Prioritize core module coverage')
}
return recommendations
}
5. 质量门禁系统
interface QualityGate {
name: string
check: () => Promise
threshold?: number
critical: boolean
}
class QualityGateKeeper {
private gates: QualityGate[] = [
{
name: 'Test Coverage',
check: async () => {
const coverage = await getCoverage()
return coverage.lines >= 80
},
threshold: 80,
critical: true
},
{
name: 'No Console Errors',
check: async () => {
const errors = await getConsoleErrors()
return errors.length === 0
},
critical: false
},
{
name: 'Bundle Size',
check: async () => {
const size = await getBundleSize()
return size {
const metrics = await measurePerformance()
return metrics.fcp {
const results: QualityGateResult[] = []
for (const gate of this.gates) {
try {
const passed = await gate.check()
results.push({
name: gate.name,
passed,
critical: gate.critical
})
} catch (error) {
results.push({
name: gate.name,
passed: false,
error: error instanceof Error ? error.message : 'Unknown error',
critical: gate.critical
})
}
}
return results
}
shouldBlockDeployment(results: QualityGateResult[]): boolean {
return results.some(r => r.critical && !r.passed)
}
}
6. 测试数据工厂
// Faker.js风格的测试数据生成
class TestDataFactory {
static task(type: TaskType = 'local_bash'): Task {
return {
id: generateTaskId(type),
type,
status: 'pending',
description: `Test task ${randomId()}`,
startTime: Date.now(),
outputFile: `/tmp/test-${randomId()}.jsonl`,
outputOffset: 0,
notified: false
}
}
static agent(name?: string): Agent {
return {
agentId: name || `test-agent-${randomId()}`,
agentType: 'coding-assistant',
whenToUse: 'For coding tasks',
model: 'claude-sonnet-4-5-20260101',
tools: ['file_read', 'file_write', 'bash'],
disallowedTools: []
}
}
static message(role: 'user' | 'assistant' = 'user'): Message {
return {
role,
content: [{
type: 'text',
text: `Test message ${randomId()}`
}],
timestamp: Date.now()
}
}
static error(code: ErrorCode = 'VALIDATION_ERROR'): ClaudeError {
return createError(code, `Test error ${randomId()}`, {
severity: 'medium',
recoverable: false
})
}
}
// 使用示例
const testTask = TestDataFactory.task('local_agent')
const testAgent = TestDataFactory.agent('my-test-agent')
const testError = TestDataFactory.error('NETWORK_ERROR')
工作流程
第一步:测试策略设计 (20 分钟)
- 识别测试金字塔层次
`` E2E Tests (10%) ↑ Integration Tests (20%) ↑ Unit Tests (70%) ``
- 确定测试优先级
``typescript const testPriority = { P0: '核心业务逻辑 - 必须测试', P1: '公共 API - 应该测试', P2: '工具函数 - 建议测试', P3: 'UI 组件 - 可选测试' } ``
第二步:测试实现 (40 分钟)
- 编写单元测试
- 编写集成测试
- 编写 E2E 测试
- 配置覆盖率检查
第三步:质量门禁配置 (15 分钟)
- 定义质量指标
- 设置阈值
- 配置 CI/CD集成
规则
- ✅ 测试应该是确定性的
- ✅ 每个测试只验证一个行为
- ✅ 使用有意义的测试名称
- ✅ 测试应该快速执行
- ✅ 保持测试独立性
- ❌ 不要测试实现细节
- ❌ 不要在测试之间共享状态
- ❌ 不要跳过失败的测试
- ❌ 不要忘记清理测试资源
输出格式
📊 测试覆盖率报告
## 覆盖率总结
| 类型 | 覆盖率 | 目标 | 状态 |
|------|--------|------|------|
| Statements | 85% | 80% | ✅ |
| Branches | 78% | 75% | ✅ |
| Functions | 92% | 85% | ✅ |
| Lines | 86% | 80% | ✅ |
## 未覆盖的关键文件
- src/core/auth.ts (45%)
- src/utils/parser.ts (62%)
🏗️ 测试架构图
展示测试层次和依赖关系。
📝 测试用例清单
提供完整的测试用例列表。
🔍 质量门禁结果
## 质量门禁检查结果
- [x] Test Coverage >= 80%
- [x] No Console Errors
- [x] Bundle Size {
describe('createUser', () => {
it('should create user with valid data', async () => {
// Arrange
// Act
// Assert
})
it('should throw on duplicate email', async () => {
// ...
})
})
})
// ❌ 糟糕的测试结构
test('works', async () => { /* ... */ })
// AI IDE 应该:建议使用描述性名称和 AAA 模式
```
2. **断言质量验证**
```typescript
// ✅ 具体的断言
expect(user.email).toBe('test@example.com')
expect(user.createdAt).toBeInstanceOf(Date)
// ❌ 模糊的断言
expect(result).toBeTruthy() // 不够具体
// AI IDE 应该:建议使用更具体的断言
```
3. **测试隔离检查**
```typescript
// ✅ 隔离的测试
beforeEach(() => {
mockRepository.reset()
})
// ❌ 共享状态的测试
let sharedState = {} // 测试间共享!
// AI IDE 应该:警告并在每个测试前重置
```
### 测试覆盖率优化
AI IDE应该提供:
- **覆盖率热点图**: 可视化未覆盖的代码
- **智能测试建议**: 基于代码分析推荐测试用例
- **回归测试选择**: 基于变更选择相关测试
- **性能分析**: 识别慢测试并优化
## AI IDE 完成后验证
### 测试质量健康度评分卡
```yaml
单元测试 (0-10分):
- 覆盖率 > 80%
- 测试速度快 ( {
// 依赖上一个测试的状态
})
// AI IDE 应该:警告并要求测试独立
// ❌ 没有时间相关的清理
beforeEach(() => {
jest.useFakeTimers()
// 但没有 afterEach 恢复
})
// AI IDE 应该:提醒添加清理代码
🟡 中等风险(建议优化)
// ⚠️ 测试太慢
it('should do something', async () => {
await sleep(5000) // 不必要的等待
}, 10000)
// AI IDE 应该:建议优化或使用 fake timers
// ⚠️ 断言不够具体
expect(result).toBeDefined()
// AI IDE 应该:建议更具体的断言
🟢 低风险(可选改进)
// 💡 可以优化的模式
const user = await createUser({
name: 'John',
email: 'john@example.com'
})
// AI IDE 可以建议:使用测试数据工厂
const user = TestDataFactory.user()
AI IDE 代码审查检查清单
在 PR/MR阶段,AI IDE应该自动检查:
单元测试
- [ ] 遵循 AAA 模式 (Arrange-Act-Assert)
- [ ] 测试名称描述行为
- [ ] 断言具体明确
- [ ] 无测试间依赖
- [ ] 清理资源完整
集成测试
- [ ] Mock 外部依赖
- [ ] 测试真实交互
- [ ] 错误处理覆盖
- [ ] 超时配置合理
E2E 测试
- [ ] 用户旅程完整
- [ ] 等待策略正确
- [ ] 截图对比配置
- [ ] 跨浏览器测试
覆盖率
- [ ] 行覆盖率 >= 80%
- [ ] 分支覆盖率 >= 75%
- [ ] 关键路径 100% 覆盖
- [ ] 新增代码有测试
质量门禁
- [ ] 所有关键门禁通过
- [ ] 性能预算符合
- [ ] 无 TypeScript 错误
- [ ] 无 ESLint 警告
AI IDE 集成实现示例
interface TestingRule {
id: string
description: string
severity: 'error' | 'warning' | 'info'
check: (testFiles: TestFile[], sourceFiles: SourceFile[]) => Violation[]
fix?: (violation: Violation) => Fix
}
const rules: TestingRule[] = [
{
id: 'TEST-001',
description: 'Tests must have descriptive names',
severity: 'warning',
check: (testFiles) => {
const vagueNames = findVagueTestNames(testFiles)
if (vagueNames.length > 0) {
return [{
message: 'Test names should describe behavior, not implementation',
location: vagueNames.map(n => n.location)
}]
}
return []
},
fix: () => ({ type: 'suggest_descriptive_name' })
},
{
id: 'TEST-002',
description: 'Tests must be isolated',
severity: 'error',
check: (testFiles) => {
const sharedState = findSharedStateBetweenTests(testFiles)
if (sharedState.length > 0) {
return [{
message: 'Tests should not share state',
location: sharedState.map(s => s.location)
}]
}
return []
},
fix: () => ({ type: 'add_reset_before_each' })
},
{
id: 'TEST-003',
description: 'Assertions should be specific',
severity: 'warning',
check: (testFiles) => {
const vagueAssertions = findVagueAssertions(testFiles)
if (vagueAssertions.length > 0) {
return [{
message: 'Use specific assertions instead of toBeTruthy()',
location: vagueAssertions.map(a => a.location)
}]
}
return []
}
},
{
id: 'TEST-004',
description: 'Tests must clean up resources',
severity: 'error',
check: (testFiles) => {
const missingCleanup = findMissingCleanup(testFiles)
if (missingCleanup.length > 0) {
return [{
message: 'Test does not clean up resources',
location: missingCleanup.map(m => m.location)
}]
}
return []
},
fix: () => ({ type: 'add_after_each_cleanup' })
},
{
id: 'TEST-005',
description: 'New code must have tests',
severity: 'error',
check: (testFiles, sourceFiles) => {
const untestedCode = findUntestedNewCode(testFiles, sourceFiles)
if (untestedCode.length > 0) {
return [{
message: 'New code paths are not covered by tests',
location: untestedCode.map(u => u.location)
}]
}
return []
}
}
// ... 更多规则
]
AI IDE 学习路径
为了让 AI IDE更好地理解测试和质量保证规范:
- 第一阶段: 学习单元测试原则和 AAA 模式
- 第二阶段: 理解集成测试和 Mock 策略
- 第三阶段: 掌握 E2E 测试和用户旅程设计
- 第四阶段: 实现覆盖率分析和质量门禁
- 第五阶段: 提供智能测试生成和优化建议
通过学习路径,AI IDE可以成长为能够独立设计和审查测试系统的专家。
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: nihao555-hub
- Source: nihao555-hub/claude-code-agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.