.claude/skills/ln-635-test-isolation-auditor/SKILL.md
Test Isolation + Anti-Patterns audit worker (L3). Checks isolation (APIs/DB/FS/Time/Random/Network), determinism (flaky, order-dependent), and 6 anti-patterns.
npx skillsauth add cbbkrd-tech/jl-finishes ln-635-test-isolation-auditorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Paths: File paths (
shared/,references/,../ln-*) are relative to skills repo root. If not found at CWD, locate this SKILL.md directory and go up one level for repo root.
Specialized worker auditing test isolation and detecting anti-patterns.
Receives contextStore with isolation checklist, anti-patterns catalog, test file list.
Good: Mocked (jest.mock, sinon, nock) Bad: Real HTTP calls to external APIs
Detection:
axios.get, fetch(, http.request without mocksSeverity: HIGH
Recommendation: Mock external APIs with nock or jest.mock
Effort: M
Good: In-memory DB (sqlite :memory:) or mocked Bad: Real database (PostgreSQL, MySQL)
Detection:
beforeAll(async () => { await db.connect() }) without :memory:Severity: MEDIUM
Recommendation: Use in-memory DB or mock DB calls
Effort: M-L
Good: Mocked (mock-fs, vol) Bad: Real file reads/writes
Detection:
fs.readFile, fs.writeFile without mocksSeverity: MEDIUM
Recommendation: Mock file system with mock-fs
Effort: S-M
Good: Mocked (jest.useFakeTimers, sinon.useFakeTimers)
Bad: new Date(), Date.now() without mocks
Detection:
new Date() in test files without useFakeTimersSeverity: MEDIUM
Recommendation: Mock time with jest.useFakeTimers()
Effort: S
Good: Seeded random (Math.seedrandom, fixed seed)
Bad: Math.random() without seed
Detection:
Math.random() without seed setupSeverity: LOW
Recommendation: Use seeded random for deterministic tests
Effort: S
Good: Mocked (supertest for Express, no real ports)
Bad: Real network requests (localhost:3000, binding to port)
Detection:
app.listen(3000) in testsSeverity: MEDIUM
Recommendation: Use supertest (no real port)
Effort: M
What: Tests that pass/fail randomly
Detection:
setTimeout, setInterval without proper awaitsSeverity: HIGH
Recommendation: Fix race conditions, use proper async/await
Effort: M-L
What: Assertions on current time (expect(timestamp).toBeCloseTo(Date.now()))
Detection:
Date.now(), new Date() in assertionsSeverity: MEDIUM
Recommendation: Mock time
Effort: S
What: Tests that fail when run in different order
Detection:
Severity: MEDIUM
Recommendation: Isolate tests, reset state in beforeEach
Effort: M
What: Global variables modified across tests
Detection:
let globalVar at module levelSeverity: MEDIUM
Recommendation: Use beforeEach to reset state
Effort: S-M
What: Test with no assertions or trivial assertion (expect().toBeTruthy())
Detection:
toBeTruthy() → LiarSeverity: HIGH
Recommendation: Add specific assertions or delete test
Effort: S
Example:
createUser() but has NO assertions — always passes even if function breakscreateUser() and asserts user.name equals 'Alice', user.id is definedWhat: Test with >100 lines, testing too many scenarios
Detection:
Severity: MEDIUM
Recommendation: Split into focused tests (one scenario per test)
Effort: S-M
What: Test taking >5 seconds to run
Detection:
Severity: MEDIUM
Recommendation: Mock external deps, use in-memory DB, parallelize
Effort: M
What: Test labeled "Unit" but not mocking dependencies
Detection:
Severity: LOW
Recommendation: Either mock dependencies OR rename to Integration test
Effort: S
What: Only testing success cases, ignoring errors
Detection:
Severity: MEDIUM
Recommendation: Add negative tests (error handling, edge cases)
Effort: M
Example:
login() with valid credentials, ignores error scenarioslogin() with invalid credentials throws 'Invalid credentials' errorWhat: Tests validating Express/Prisma/bcrypt (NOT our code)
Detection:
Severity: MEDIUM
Recommendation: Delete framework tests
Effort: S
MANDATORY READ: Load shared/references/audit_scoring.md for unified scoring formula.
Severity mapping:
Return JSON to coordinator (flat findings array):
{
"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 principle field prefix (Test Isolation / Determinism / Anti-Patterns) to identify issue category.
principle prefix to distinguishshared/references/audit_scoring.mdshared/references/audit_scoring.mdshared/references/audit_output_schema.mdVersion: 3.0.0 Last Updated: 2025-12-23
testing
When the user wants to plan a content strategy, decide what content to create, or figure out what topics to cover. Also use when the user mentions "content strategy," "what should I write about," "content ideas," "blog strategy," "topic clusters," or "content planning." For writing individual pieces, see copywriting. For SEO-specific audits, see seo-audit.
development
When the user wants to create competitor comparison or alternative pages for SEO and sales enablement. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' or 'competitive landing pages.' Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. Emphasizes deep research, modular content architecture, and varied section types beyond feature tables.
development
Write B2B cold emails and follow-up sequences that get replies. Use when the user wants to write cold outreach emails, prospecting emails, cold email campaigns, sales development emails, or SDR emails. Covers subject lines, opening lines, body copy, CTAs, personalization, and multi-touch follow-up sequences.
development
When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' or 'involuntary churn.' This skill covers voluntary churn (cancel flows, save offers, exit surveys) and involuntary churn (dunning, payment recovery). For post-cancel win-back email sequences, see email-sequence. For in-app upgrade paywalls, see paywall-upgrade-cro.