ln-635-test-isolation-auditor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTest Isolation & Anti-Patterns Auditor (L3 Worker)
测试隔离与反模式审计器(L3工作器)
Specialized worker auditing test isolation and detecting anti-patterns.
专注于审计测试隔离性并检测反模式的工作器。
Purpose & Scope
目标与范围
- Worker in ln-630 coordinator pipeline
- Audit Test Isolation (Category 5: Medium Priority)
- Audit Anti-Patterns (Category 6: Medium Priority)
- Check determinism (no flaky tests)
- Calculate compliance score (X/10)
- ln-630协调器流水线中的工作器
- 审计测试隔离性(类别5:中等优先级)
- 审计反模式(类别6:中等优先级)
- 检查确定性(无不稳定测试)
- 计算合规分数(X/10)
Inputs (from Coordinator)
输入(来自协调器)
Receives with isolation checklist, anti-patterns catalog, test file list.
contextStore接收包含隔离性检查清单、反模式目录、测试文件列表的。
contextStoreWorkflow
工作流程
- Parse context
- Check isolation for 6 categories
- Check determinism
- Detect 6 anti-patterns
- Collect findings
- Calculate score
- Return JSON
- 解析上下文
- 检查6类隔离性
- 检查确定性
- 检测6种反模式
- 收集问题结果
- 计算分数
- 返回JSON
Audit Rules: Test Isolation
审计规则:测试隔离性
1. External APIs
1. 外部API
Good: Mocked (jest.mock, sinon, nock)
Bad: Real HTTP calls to external APIs
Detection:
- Grep for ,
axios.get,fetch(without mockshttp.request - Check if test makes actual network calls
Severity: HIGH
Recommendation: Mock external APIs with or
nockjest.mockEffort: M
良好实践: 已Mock(jest.mock、sinon、nock)
不良实践: 对外部API发起真实HTTP请求
检测方式:
- 搜索、
axios.get、fetch(且未使用Mock的情况http.request - 检查测试是否发起实际网络请求
严重程度: 高
建议: 使用或Mock外部API
nockjest.mock整改工作量: M
2. Database
2. 数据库
Good: In-memory DB (sqlite :memory:) or mocked
Bad: Real database (PostgreSQL, MySQL)
Detection:
- Check DB connection strings (localhost:5432, real DB URL)
- Grep for without
beforeAll(async () => { await db.connect() }):memory:
Severity: MEDIUM
Recommendation: Use in-memory DB or mock DB calls
Effort: M-L
良好实践: 内存数据库(sqlite :memory:)或已Mock
不良实践: 真实数据库(PostgreSQL、MySQL)
检测方式:
- 检查数据库连接字符串(localhost:5432、真实数据库URL)
- 搜索且未使用
beforeAll(async () => { await db.connect() })的情况:memory:
严重程度: 中
建议: 使用内存数据库或Mock数据库调用
整改工作量: M-L
3. File System
3. 文件系统
Good: Mocked (mock-fs, vol)
Bad: Real file reads/writes
Detection:
- Grep for ,
fs.readFilewithout mocksfs.writeFile - Check if test creates/deletes real files
Severity: MEDIUM
Recommendation: Mock file system with
mock-fsEffort: S-M
良好实践: 已Mock(mock-fs、vol)
不良实践: 真实文件读/写操作
检测方式:
- 搜索、
fs.readFile且未使用Mock的情况fs.writeFile - 检查测试是否创建/删除真实文件
严重程度: 中
建议: 使用Mock文件系统
mock-fs整改工作量: S-M
4. Time/Date
4. 时间/日期
Good: Mocked (jest.useFakeTimers, sinon.useFakeTimers)
Bad: , without mocks
new Date()Date.now()Detection:
- Grep for in test files without
new Date()useFakeTimers
Severity: MEDIUM
Recommendation: Mock time with
jest.useFakeTimers()Effort: S
良好实践: 已Mock(jest.useFakeTimers、sinon.useFakeTimers)
不良实践: 未Mock的、
new Date()Date.now()检测方式:
- 搜索测试文件中未搭配的
useFakeTimersnew Date()
严重程度: 中
建议: 使用Mock时间
jest.useFakeTimers()整改工作量: S
5. Random
5. 随机数
Good: Seeded random (Math.seedrandom, fixed seed)
Bad: without seed
Math.random()Detection:
- Grep for without seed setup
Math.random()
Severity: LOW
Recommendation: Use seeded random for deterministic tests
Effort: S
良好实践: 带种子的随机数(Math.seedrandom、固定种子)
不良实践: 未设置种子的
Math.random()检测方式:
- 搜索未设置种子的
Math.random()
严重程度: 低
建议: 使用带种子的随机数以保证测试确定性
整改工作量: S
6. Network
6. 网络
Good: Mocked (supertest for Express, no real ports)
Bad: Real network requests (, binding to port)
localhost:3000Detection:
- Grep for in tests
app.listen(3000) - Check for real HTTP requests
Severity: MEDIUM
Recommendation: Use (no real port)
supertestEffort: M
良好实践: 已Mock(Express使用supertest,不使用真实端口)
不良实践: 真实网络请求(、绑定到真实端口)
localhost:3000检测方式:
- 搜索测试中的
app.listen(3000) - 检查是否存在真实HTTP请求
严重程度: 中
建议: 使用(不使用真实端口)
supertest整改工作量: M
Audit Rules: Determinism
审计规则:确定性
1. Flaky Tests
1. 不稳定测试
What: Tests that pass/fail randomly
Detection:
- Run tests multiple times, check for inconsistent results
- Grep for ,
setTimeoutwithout proper awaitssetInterval - Check for race conditions (async operations not awaited)
Severity: HIGH
Recommendation: Fix race conditions, use proper async/await
Effort: M-L
定义: 随机通过/失败的测试
检测方式:
- 多次运行测试,检查结果是否不一致
- 搜索未正确使用await的、
setTimeoutsetInterval - 检查是否存在竞态条件(未等待的异步操作)
严重程度: 高
建议: 修复竞态条件,正确使用async/await
整改工作量: M-L
2. Time-Dependent Assertions
2. 时间依赖断言
What: Assertions on current time ()
expect(timestamp).toBeCloseTo(Date.now())Detection:
- Grep for ,
Date.now()in assertionsnew Date()
Severity: MEDIUM
Recommendation: Mock time
Effort: S
定义: 对当前时间的断言()
expect(timestamp).toBeCloseTo(Date.now())检测方式:
- 搜索断言中的、
Date.now()new Date()
严重程度: 中
建议: Mock时间
整改工作量: S
3. Order-Dependent Tests
3. 顺序依赖测试
What: Tests that fail when run in different order
Detection:
- Run tests in random order, check for failures
- Grep for shared mutable state between tests
Severity: MEDIUM
Recommendation: Isolate tests, reset state in beforeEach
Effort: M
定义: 运行顺序改变时会失败的测试
检测方式:
- 随机顺序运行测试,检查是否失败
- 搜索测试间共享的可变状态
严重程度: 中
建议: 隔离测试,在beforeEach中重置状态
整改工作量: M
4. Shared Mutable State
4. 共享可变状态
What: Global variables modified across tests
Detection:
- Grep for at module level
let globalVar - Check for state shared between tests
Severity: MEDIUM
Recommendation: Use to reset state
beforeEachEffort: S-M
定义: 跨测试修改的全局变量
检测方式:
- 搜索模块级别的
let globalVar - 检查测试间是否存在共享状态
严重程度: 中
建议: 使用重置状态
beforeEach整改工作量: S-M
Audit Rules: Anti-Patterns
审计规则:反模式
1. The Liar (Always Passes)
1. 说谎者(始终通过)
What: Test with no assertions or trivial assertion ()
expect().toBeTruthy()Detection:
- Count assertions per test
- If 0 assertions or only → Liar
toBeTruthy()
Severity: HIGH
Recommendation: Add specific assertions or delete test
Effort: S
Example:
- BAD (Liar): Test calls but has NO assertions — always passes even if function breaks
createUser() - GOOD: Test calls and asserts
createUser()equals 'Alice',user.nameis defineduser.id
定义: 没有断言或仅包含 trivial 断言()的测试
expect().toBeTruthy()检测方式:
- 统计每个测试的断言数量
- 若断言数为0或仅使用→ 属于说谎者
toBeTruthy()
严重程度: 高
建议: 添加具体断言或删除测试
整改工作量: S
示例:
- 不良实践(说谎者): 测试调用但无任何断言——即使函数出错也始终通过
createUser() - 良好实践: 测试调用并断言
createUser()等于'Alice'、user.name已定义user.id
2. The Giant (>100 lines)
2. 巨人(超过100行)
What: Test with >100 lines, testing too many scenarios
Detection:
- Count lines per test
- If >100 lines → Giant
Severity: MEDIUM
Recommendation: Split into focused tests (one scenario per test)
Effort: S-M
定义: 超过100行、测试过多场景的测试
检测方式:
- 统计每个测试的行数
- 若超过100行 → 属于巨人
严重程度: 中
建议: 拆分为聚焦的测试(每个测试对应一个场景)
整改工作量: S-M
3. Slow Poke (>5 seconds)
3. 慢乌龟(超过5秒)
What: Test taking >5 seconds to run
Detection:
- Measure test duration
- If >5s → Slow Poke
Severity: MEDIUM
Recommendation: Mock external deps, use in-memory DB, parallelize
Effort: M
定义: 运行时间超过5秒的测试
检测方式:
- 测量测试运行时长
- 若超过5秒 → 属于慢乌龟
严重程度: 中
建议: Mock外部依赖,使用内存数据库,并行化测试
整改工作量: M
4. Conjoined Twins (Unit test without mocks = Integration)
4. 连体双胞胎(无Mock的单元测试=集成测试)
What: Test labeled "Unit" but not mocking dependencies
Detection:
- Check if test name includes "Unit"
- Verify all dependencies are mocked
- If no mocks → actually Integration test
Severity: LOW
Recommendation: Either mock dependencies OR rename to Integration test
Effort: S
定义: 标记为“单元测试”但未Mock依赖的测试
检测方式:
- 检查测试名称是否包含“Unit”
- 验证所有依赖是否已Mock
- 若未使用Mock → 实际为集成测试
严重程度: 低
建议: 要么Mock依赖,要么重命名为集成测试
整改工作量: S
5. Happy Path Only (No error scenarios)
5. 仅快乐路径(无错误场景)
What: Only testing success cases, ignoring errors
Detection:
- For each function, check if test covers error cases
- If only positive scenarios → Happy Path Only
Severity: MEDIUM
Recommendation: Add negative tests (error handling, edge cases)
Effort: M
Example:
- BAD (Happy Path Only): Test only checks with valid credentials, ignores error scenarios
login() - GOOD: Add negative test that verifies with invalid credentials throws 'Invalid credentials' error
login()
定义: 仅测试成功场景,忽略错误情况
检测方式:
- 针对每个函数,检查测试是否覆盖错误场景
- 若仅包含正向场景 → 属于仅快乐路径
严重程度: 中
建议: 添加负面测试(错误处理、边缘情况)
整改工作量: M
示例:
- 不良实践(仅快乐路径): 测试仅检查有效凭证的,忽略错误场景
login() - 良好实践: 添加负面测试,验证使用无效凭证调用时会抛出'Invalid credentials'错误
login()
6. Framework Tester (Tests framework behavior)
6. 框架测试器(测试框架行为)
What: Tests validating Express/Prisma/bcrypt (NOT our code)
Detection:
- Already detected by ln-631-test-business-logic-auditor
- Cross-reference findings
Severity: MEDIUM
Recommendation: Delete framework tests
Effort: S
定义: 验证Express/Prisma/bcrypt的测试(而非我们的代码)
检测方式:
- 已由ln-631-test-business-logic-auditor检测
- 交叉引用检测结果
严重程度: 中
建议: 删除框架测试
整改工作量: S
Scoring Algorithm
评分算法
See for unified formula and score interpretation.
shared/references/audit_scoring.mdSeverity mapping:
- Flaky tests, External API not mocked, The Liar → HIGH
- Real database, File system, Time/Date, Network, The Giant, Happy Path Only → MEDIUM
- Random without seed, Order-dependent, Conjoined Twins → LOW
统一公式及分数解释请参见。
shared/references/audit_scoring.md严重程度映射:
- 不稳定测试、未Mock外部API、说谎者 → 高
- 真实数据库、文件系统、时间/日期、网络、巨人、仅快乐路径 → 中
- 未设置种子的随机数、顺序依赖、连体双胞胎 → 低
Output Format
输出格式
Return JSON to coordinator (flat findings array):
json
{
"category": "Isolation & Anti-Patterns",
"score": 6,
"total_issues": 18,
"critical": 0,
"high": 5,
"medium": 10,
"low": 3,
"checks": [
{"id": "api_isolation", "name": "API Isolation", "status": "failed", "details": "2 tests make real HTTP calls"},
{"id": "db_isolation", "name": "Database Isolation", "status": "warning", "details": "1 test uses real PostgreSQL"},
{"id": "fs_isolation", "name": "File System Isolation", "status": "passed", "details": "All FS calls mocked"},
{"id": "time_isolation", "name": "Time Isolation", "status": "passed", "details": "All Date/Time mocked"},
{"id": "flaky_tests", "name": "Flaky Tests", "status": "failed", "details": "3 race conditions detected"},
{"id": "anti_patterns", "name": "Anti-Patterns", "status": "warning", "details": "2 Liars, 1 Giant found"}
],
"findings": [
{
"severity": "HIGH",
"location": "user.test.ts:45-52",
"issue": "External API not mocked — test makes real HTTP call to https://api.github.com",
"principle": "Test Isolation / External APIs",
"recommendation": "Mock external API with nock or jest.mock",
"effort": "M"
},
{
"severity": "HIGH",
"location": "async.test.ts:28-35",
"issue": "Flaky test (race condition) — setTimeout without proper await",
"principle": "Determinism / Race Condition",
"recommendation": "Fix race condition with proper async/await",
"effort": "M"
},
{
"severity": "HIGH",
"location": "user.test.ts:45",
"issue": "Anti-pattern 'The Liar' — test 'createUser works' has no assertions",
"principle": "Anti-Patterns / The Liar",
"recommendation": "Add specific assertions or delete test",
"effort": "S"
},
{
"severity": "MEDIUM",
"location": "db.test.ts:12",
"issue": "Real database used — test connects to localhost:5432 PostgreSQL",
"principle": "Test Isolation / Database",
"recommendation": "Use in-memory SQLite (:memory:) or mock DB",
"effort": "L"
},
{
"severity": "MEDIUM",
"location": "order.test.ts:200-350",
"issue": "Anti-pattern 'The Giant' — test 'order flow' is 150 lines (>100)",
"principle": "Anti-Patterns / The Giant",
"recommendation": "Split into focused tests (one scenario per test)",
"effort": "M"
},
{
"severity": "MEDIUM",
"location": "payment.test.ts",
"issue": "Anti-pattern 'Happy Path Only' — only success scenarios, no error tests",
"principle": "Anti-Patterns / Happy Path Only",
"recommendation": "Add negative tests for error handling",
"effort": "M"
}
]
}Note: Findings are flattened into single array. Use field prefix (Test Isolation / Determinism / Anti-Patterns) to identify issue category.
principle向协调器返回JSON(扁平化结果数组):
json
{
"category": "Isolation & Anti-Patterns",
"score": 6,
"total_issues": 18,
"critical": 0,
"high": 5,
"medium": 10,
"low": 3,
"checks": [
{"id": "api_isolation", "name": "API Isolation", "status": "failed", "details": "2 tests make real HTTP calls"},
{"id": "db_isolation", "name": "Database Isolation", "status": "warning", "details": "1 test uses real PostgreSQL"},
{"id": "fs_isolation", "name": "File System Isolation", "status": "passed", "details": "All FS calls mocked"},
{"id": "time_isolation", "name": "Time Isolation", "status": "passed", "details": "All Date/Time mocked"},
{"id": "flaky_tests", "name": "Flaky Tests", "status": "failed", "details": "3 race conditions detected"},
{"id": "anti_patterns", "name": "Anti-Patterns", "status": "warning", "details": "2 Liars, 1 Giant found"}
],
"findings": [
{
"severity": "HIGH",
"location": "user.test.ts:45-52",
"issue": "External API not mocked — test makes real HTTP call to https://api.github.com",
"principle": "Test Isolation / External APIs",
"recommendation": "Mock external API with nock or jest.mock",
"effort": "M"
},
{
"severity": "HIGH",
"location": "async.test.ts:28-35",
"issue": "Flaky test (race condition) — setTimeout without proper await",
"principle": "Determinism / Race Condition",
"recommendation": "Fix race condition with proper async/await",
"effort": "M"
},
{
"severity": "HIGH",
"location": "user.test.ts:45",
"issue": "Anti-pattern 'The Liar' — test 'createUser works' has no assertions",
"principle": "Anti-Patterns / The Liar",
"recommendation": "Add specific assertions or delete test",
"effort": "S"
},
{
"severity": "MEDIUM",
"location": "db.test.ts:12",
"issue": "Real database used — test connects to localhost:5432 PostgreSQL",
"principle": "Test Isolation / Database",
"recommendation": "Use in-memory SQLite (:memory:) or mock DB",
"effort": "L"
},
{
"severity": "MEDIUM",
"location": "order.test.ts:200-350",
"issue": "Anti-pattern 'The Giant' — test 'order flow' is 150 lines (>100)",
"principle": "Anti-Patterns / The Giant",
"recommendation": "Split into focused tests (one scenario per test)",
"effort": "M"
},
{
"severity": "MEDIUM",
"location": "payment.test.ts",
"issue": "Anti-pattern 'Happy Path Only' — only success scenarios, no error tests",
"principle": "Anti-Patterns / Happy Path Only",
"recommendation": "Add negative tests for error handling",
"effort": "M"
}
]
}注意: 结果被扁平化为单个数组。使用字段前缀(测试隔离/确定性/反模式)识别问题类别。
principleReference Files
参考文件
- Audit scoring formula:
shared/references/audit_scoring.md - Audit output schema:
shared/references/audit_output_schema.md
Version: 3.0.0
Last Updated: 2025-12-23
- 审计评分公式:
shared/references/audit_scoring.md - 审计输出 schema:
shared/references/audit_output_schema.md
版本: 3.0.0
最后更新: 2025-12-23