Test Quality Audit by auldsyababua/instructor-workflow
npx skills add https://github.com/auldsyababua/instructor-workflow --skill 'Test Quality Audit'在以下情况时使用此技能:
触发场景:
需要警惕的危险信号:
针对代码审查(特定于 PR):
针对系统性审计(全代码库):
*.test.js、*.spec.ts、、广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
*_test.pytest_*.py对测试文件运行以下检查:
目的:检测在已提交代码中被跳过或禁用的测试
待检测模式:
// JavaScript/TypeScript:
describe.skip("...", ...)
it.skip("...", ...)
test.skip("...", ...)
it.only("...", ...) // 严重:意味着其他测试被忽略
test.only("...", ...)
// Python:
@unittest.skip("...")
@pytest.mark.skip
pytest.skip()
# TODO: fix this test
扫描命令:
# JavaScript/TypeScript:
grep -rn -E "\.(skip|only)\(" tests/ spec/ __tests__/
# Python:
grep -rn -E "(@unittest\.skip|@pytest\.mark\.skip|pytest\.skip\(|# TODO.*test)" tests/
严重性:
.only()(所有其他测试被忽略).skip() 但没有问题引用或理由说明.skip() 并带有 TODO 注释但没有时间线通过标准:没有禁用的测试,或者所有禁用的测试都满足:
# LAW-123: Re-enable when feature X ships)目的:检测未验证有意义行为的断言
待检测模式:
// JavaScript/TypeScript:
expect(true).toBe(true)
expect(result).toBeDefined()
expect(response).toBeTruthy()
expect(error).toBeFalsy() // 错误被吞没!
// Python:
assert True
assert result is not None
assert response # 模糊的断言
扫描命令:
# JavaScript/TypeScript:
grep -rn -E "(expect\(true\)|expect\(false\)|\.toBeTruthy\(\)|\.toBeFalsy\(\)|\.toBeDefined\(\))" tests/ spec/
# Python:
grep -rn -E "(assert True|assert False|assert [a-zA-Z_]+ is not None)" tests/
严重性:
expect(true).toBe(true))toBeDefined() 但未验证实际值通过标准:所有断言都验证特定的预期值或行为
目的:检测在没有断言的情况下抑制错误的 try/catch 块
待检测模式:
// JavaScript/TypeScript:
try {
// ... 测试代码 ...
} catch (error) {
// 没有对错误进行断言 - 被吞没了!
}
// 没有验证的宽泛捕获:
try {
await riskyOperation()
} catch (e) {
console.log(e) // 记录了但没有断言
}
# Python:
try:
# ... 测试代码 ...
except Exception:
pass # 错误被吞没!
# 没有断言的宽泛异常捕获:
try:
risky_operation()
except Exception as e:
print(e) # 记录了但没有断言
需要手动审查:此模式需要阅读测试代码上下文
检查内容:
catch (Exception) 是可疑的)严重性:
通过标准:所有 try/catch 块要么:
Exception 捕获)目的:检测被模拟/常量替换但未说明理由的 HTTP 调用
待检测模式:
// JavaScript/TypeScript:
// const response = await fetch('/api/endpoint')
const response = { status: 200, data: mockData }
// await api.createUser(userData)
// 注释掉了实际的 API 调用
扫描命令:
# 查找注释掉的 HTTP 调用:
grep -rn -E "// .*(fetch\(|axios\.|http\.|api\.)" tests/ spec/
严重性:
通过标准:所有模拟的 HTTP 调用要么:
目的:检测为使测试通过而被削弱的测试(而非修复代码)
需要手动审查:比较 PR 差异中的测试变更
待检测模式:
在 PR 差异中检查:
- expect(result.users).toHaveLength(5)
+ expect(result.users).toHaveLength(3) // 为什么更改?是错误还是功能?
- expect(response.status).toBe(200)
+ // 状态检查被移除 - 为什么?
- expect(() => validateInput('')).toThrow('Input required')
+ expect(() => validateInput('')).not.toThrow() // 验证被移除了?
严重性:
通过标准:所有测试弱化变更都需有:
目的:检测通过忽略模式绕过的安全验证
待检测模式:
// eslint-disable security/detect-non-literal-fs-filename
// eslint-disable-next-line security/detect-unsafe-regex
// prettier-ignore
扫描命令:
# 查找与安全相关的 linter 禁用:
grep -rn -E "(eslint-disable.*security|nosec|# noqa.*security)" tests/ src/
严重性:
通过标准:所有安全 linter 禁用都需有:
按严重性组织所有检测到的反模式:
严重(阻止合并):
.only()(所有其他测试被忽略)高(批准前需要修复):
中(请求修复,但可以带警告批准):
信息(改进建议):
如果发现反模式,生成报告:
**测试质量审计结果**
⚠️ **发现问题** - 检测到测试质量问题
### 严重问题(合并前必须修复)
1. **使用 .only() 禁用的测试** (tests/user.test.ts:45):
- 模式:`it.only("creates user", ...)`
- 问题:套件中的所有其他测试被忽略
- 修复:移除 `.only()` 或解释为何只应运行此测试
2. **空 Catch 块** (tests/api.test.ts:89):
- 模式:`catch (error) { /* empty */ }`
- 问题:错误被吞没而没有断言
- 修复:断言预期的错误或移除 try/catch
### 高优先级问题(建议修复)
3. **没有理由说明的禁用测试** (tests/auth.test.ts:120):
- 模式:`it.skip("validates token expiry", ...)`
- 问题:没有 Linear 问题或跳过理由说明
- 修复:添加问题引用或重新启用测试
4. **琐碎断言** (tests/validation.test.ts:67):
- 模式:`expect(true).toBe(true)`
- 问题:断言未验证实际行为
- 修复:断言特定的验证结果
### 中优先级问题(警告)
5. **模糊断言** (tests/response.test.ts:34):
- 模式:`expect(response).toBeDefined()`
- 问题:未验证响应内容
- 修复:断言特定的响应字段(状态、数据等)
**建议**:[阻止 | 请求修复 | 带警告批准]
如果审计通过,确认质量:
**测试质量审计结果**
✅ **通过** - 未发现测试质量问题
所有检查通过:
- [x] 没有无理由说明的禁用测试
- [x] 所有断言都验证了特定行为
- [x] 错误处理包含断言
- [x] 没有 HTTP 调用被内联模拟替换
- [x] 未检测到测试弱化
- [x] 安全 linter 规则被正确应用
**建议**:批准合并
// 错误示例:
it.skip("validates email format", () => {
// 测试被禁用,没有解释原因
})
// 正确示例:
// LAW-456: Re-enable when email validation RFC compliance added
it.skip("validates email format per RFC 5322", () => {
// 测试被禁用,有明确的跟踪问题引用
})
// 错误示例:
it("creates user", async () => {
const result = await createUser(userData)
expect(result).toBeDefined() // 模糊 - 结果具体是什么?
})
// 正确示例:
it("creates user", async () => {
const result = await createUser(userData)
expect(result.id).toBeDefined()
expect(result.email).toBe(userData.email)
expect(result.status).toBe("active")
})
// 错误示例:
it("handles invalid input", async () => {
try {
await processInput(null)
} catch (error) {
console.log(error) // 记录了但没有断言
}
})
// 正确示例:
it("handles invalid input", async () => {
await expect(processInput(null)).rejects.toThrow("Input cannot be null")
})
// 错误示例:
it("fetches user data", async () => {
// const response = await fetch('/api/users/123')
const response = { id: 123, name: "Test User" } // 内联模拟
expect(response.name).toBe("Test User")
})
// 正确示例:
it("fetches user data", async () => {
// 在框架层面模拟,而非内联
jest.spyOn(api, "getUser").mockResolvedValue({ id: 123, name: "Test User" })
const response = await fetchUserData(123)
expect(response.name).toBe("Test User")
expect(api.getUser).toHaveBeenCalledWith(123)
})
grep:用于反模式检测的模式匹配docs/agents/qa/qa-agent.md(测试质量标准部分)/security-validate - 安全验证模式/test-standards - 全面的测试质量验证(如果可用)test-audit-protocol.md - 全面的测试审计流程扫描禁用的测试:
# JavaScript/TypeScript:
grep -rn -E "\.(skip|only)\(" tests/ spec/ __tests__/
# Python:
grep -rn -E "(@unittest\.skip|@pytest\.mark\.skip|pytest\.skip\()" tests/
扫描琐碎断言:
# JavaScript/TypeScript:
grep -rn -E "(expect\(true\)|expect\(false\)|\.toBeTruthy\(\)|\.toBeFalsy\(\)|\.toBeDefined\(\))" tests/
# Python:
grep -rn -E "(assert True|assert False)" tests/
扫描注释掉的 HTTP 调用:
grep -rn -E "// .*(fetch\(|axios\.|http\.|api\.)" tests/
扫描安全 linter 抑制:
grep -rn -E "(eslint-disable.*security|nosec|# noqa.*security)" tests/ src/
每周安装次数
0
代码仓库
GitHub 星标数
3
首次出现
1970年1月1日
安全审计
Use this skill when you need to:
Triggers :
Red Flags to Watch For :
For code review (PR-specific) :
For systematic audit (codebase-wide) :
*.test.js, *.spec.ts, *_test.py, test_*.pyRun the following checks on test files:
Purpose : Detect tests that are skipped or disabled in committed code
Patterns to detect :
// JavaScript/TypeScript:
describe.skip("...", ...)
it.skip("...", ...)
test.skip("...", ...)
it.only("...", ...) // CRITICAL: Means other tests are ignored
test.only("...", ...)
// Python:
@unittest.skip("...")
@pytest.mark.skip
pytest.skip()
# TODO: fix this test
Scan command :
# JavaScript/TypeScript:
grep -rn -E "\.(skip|only)\(" tests/ spec/ __tests__/
# Python:
grep -rn -E "(@unittest\.skip|@pytest\.mark\.skip|pytest\.skip\(|# TODO.*test)" tests/
Severity :
.only() in committed code (all other tests ignored).skip() without issue reference or justification.skip() with TODO comment but no timelinePass Criteria : No disabled tests, OR all disabled tests have:
# LAW-123: Re-enable when feature X ships)Purpose : Detect assertions that don't validate meaningful behavior
Patterns to detect :
// JavaScript/TypeScript:
expect(true).toBe(true)
expect(result).toBeDefined()
expect(response).toBeTruthy()
expect(error).toBeFalsy() // Error swallowing!
// Python:
assert True
assert result is not None
assert response # Vague assertion
Scan command :
# JavaScript/TypeScript:
grep -rn -E "(expect\(true\)|expect\(false\)|\.toBeTruthy\(\)|\.toBeFalsy\(\)|\.toBeDefined\(\))" tests/ spec/
# Python:
grep -rn -E "(assert True|assert False|assert [a-zA-Z_]+ is not None)" tests/
Severity :
expect(true).toBe(true))toBeDefined() without validating actual valuePass Criteria : All assertions validate specific expected values or behaviors
Purpose : Detect try/catch blocks that suppress errors without assertions
Patterns to detect :
// JavaScript/TypeScript:
try {
// ... test code ...
} catch (error) {
// No assertion on error - swallowed!
}
// Broad catch without validation:
try {
await riskyOperation()
} catch (e) {
console.log(e) // Logged but not asserted
}
# Python:
try:
# ... test code ...
except Exception:
pass # Error swallowed!
# Broad except without assertion:
try:
risky_operation()
except Exception as e:
print(e) # Logged but not asserted
Manual Review Required : This pattern requires reading test code context
Check for :
catch (Exception) is suspicious)Severity :
Pass Criteria : All try/catch blocks either:
Exception catch)Purpose : Detect HTTP calls replaced with mocks/constants without rationale
Patterns to detect :
// JavaScript/TypeScript:
// const response = await fetch('/api/endpoint')
const response = { status: 200, data: mockData }
// await api.createUser(userData)
// Commented out actual API call
Scan command :
# Look for commented HTTP calls:
grep -rn -E "// .*(fetch\(|axios\.|http\.|api\.)" tests/ spec/
Severity :
Pass Criteria : All mocked HTTP calls either:
Purpose : Detect tests weakened to make them pass (instead of fixing code)
Manual Review Required : Compare test changes in PR diff
Patterns to detect :
Check in PR diff :
- expect(result.users).toHaveLength(5)
+ expect(result.users).toHaveLength(3) // Why changed? Bug or feature?
- expect(response.status).toBe(200)
+ // Status check removed - why?
- expect(() => validateInput('')).toThrow('Input required')
+ expect(() => validateInput('')).not.toThrow() // Validation removed?
Severity :
Pass Criteria : All test weakening changes are justified with:
Purpose : Detect security validation bypassed via ignore patterns
Patterns to detect :
// eslint-disable security/detect-non-literal-fs-filename
// eslint-disable-next-line security/detect-unsafe-regex
// prettier-ignore
Scan command :
# Look for security-related linter disables:
grep -rn -E "(eslint-disable.*security|nosec|# noqa.*security)" tests/ src/
Severity :
Pass Criteria : All security linter disables have:
Organize all detected anti-patterns by severity:
CRITICAL (blocks merge) :
.only() in committed tests (all other tests ignored)HIGH (requires fix before approval) :
MEDIUM (request fix, but can approve with warning) :
INFO (feedback for improvement) :
If anti-patterns found , generate a report:
**Test Quality Audit Results**
⚠️ **ISSUES FOUND** - Test quality concerns detected
### Critical Issues (Must Fix Before Merge)
1. **Disabled Test with .only()** (tests/user.test.ts:45):
- Pattern: `it.only("creates user", ...)`
- Issue: All other tests in suite are ignored
- Fix: Remove `.only()` or explain why only this test should run
2. **Empty Catch Block** (tests/api.test.ts:89):
- Pattern: `catch (error) { /* empty */ }`
- Issue: Errors swallowed without assertion
- Fix: Assert on expected error or remove try/catch
### High Priority Issues (Fix Recommended)
3. **Disabled Test Without Justification** (tests/auth.test.ts:120):
- Pattern: `it.skip("validates token expiry", ...)`
- Issue: No Linear issue or explanation for skip
- Fix: Add issue reference or re-enable test
4. **Trivial Assertion** (tests/validation.test.ts:67):
- Pattern: `expect(true).toBe(true)`
- Issue: Assertion doesn't validate actual behavior
- Fix: Assert on specific validation result
### Medium Priority Issues (Warnings)
5. **Vague Assertion** (tests/response.test.ts:34):
- Pattern: `expect(response).toBeDefined()`
- Issue: Doesn't validate response contents
- Fix: Assert on specific response fields (status, data, etc.)
**Recommendation**: [BLOCKED | REQUEST FIXES | APPROVED WITH WARNINGS]
If audit passes , confirm quality:
**Test Quality Audit Results**
✅ **PASSED** - No test quality issues found
All checks passed:
- [x] No disabled tests without justification
- [x] All assertions validate specific behaviors
- [x] Error handling includes assertions
- [x] No HTTP calls replaced with inline mocks
- [x] No test weakening detected
- [x] Security linter rules properly applied
**Recommendation**: APPROVED for merge
// Bad example:
it.skip("validates email format", () => {
// Test disabled, no explanation why
})
// Good example:
// LAW-456: Re-enable when email validation RFC compliance added
it.skip("validates email format per RFC 5322", () => {
// Test disabled with clear reference to tracking issue
})
// Bad example:
it("creates user", async () => {
const result = await createUser(userData)
expect(result).toBeDefined() // Vague - what about result?
})
// Good example:
it("creates user", async () => {
const result = await createUser(userData)
expect(result.id).toBeDefined()
expect(result.email).toBe(userData.email)
expect(result.status).toBe("active")
})
// Bad example:
it("handles invalid input", async () => {
try {
await processInput(null)
} catch (error) {
console.log(error) // Logged but not asserted
}
})
// Good example:
it("handles invalid input", async () => {
await expect(processInput(null)).rejects.toThrow("Input cannot be null")
})
// Bad example:
it("fetches user data", async () => {
// const response = await fetch('/api/users/123')
const response = { id: 123, name: "Test User" } // Inline mock
expect(response.name).toBe("Test User")
})
// Good example:
it("fetches user data", async () => {
// Mock at framework level, not inline
jest.spyOn(api, "getUser").mockResolvedValue({ id: 123, name: "Test User" })
const response = await fetchUserData(123)
expect(response.name).toBe("Test User")
expect(api.getUser).toHaveBeenCalledWith(123)
})
grep: Pattern matching for anti-pattern detectiondocs/agents/qa/qa-agent.md (Test Quality Standards section)/security-validate - Security validation patterns/test-standards - Comprehensive test quality validation (if available)test-audit-protocol.md - Comprehensive test audit proceduresScan for disabled tests :
# JavaScript/TypeScript:
grep -rn -E "\.(skip|only)\(" tests/ spec/ __tests__/
# Python:
grep -rn -E "(@unittest\.skip|@pytest\.mark\.skip|pytest\.skip\()" tests/
Scan for trivial assertions :
# JavaScript/TypeScript:
grep -rn -E "(expect\(true\)|expect\(false\)|\.toBeTruthy\(\)|\.toBeFalsy\(\)|\.toBeDefined\(\))" tests/
# Python:
grep -rn -E "(assert True|assert False)" tests/
Scan for commented HTTP calls :
grep -rn -E "// .*(fetch\(|axios\.|http\.|api\.)" tests/
Scan for security linter suppression :
grep -rn -E "(eslint-disable.*security|nosec|# noqa.*security)" tests/ src/
Weekly Installs
0
Repository
GitHub Stars
3
First Seen
Jan 1, 1970
Security Audits
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
140,500 周安装