{"id":"1d4aba20-4d00-4233-961c-f0a5801f5331","shortId":"aQcufj","kind":"skill","title":"testing-best-practices","tagline":"Unit testing, integration testing, and test-driven development principles. Use when writing tests, reviewing test code, improving test coverage, or setting up testing strategy. Triggers on \"write tests\", \"review tests\", \"testing best practices\", or \"TDD\".","description":"# Testing Best Practices\n\nUnit testing, integration testing, and TDD principles for reliable, maintainable test suites. Contains 34 rules across 7 categories using TypeScript with Jest/Vitest.\n\n## Metadata\n\n- **Version:** 2.0.0\n- **Rule Count:** 34 rules across 7 categories\n- **License:** MIT\n\n## When to Apply\n\nReference these guidelines when:\n- Writing unit or integration tests\n- Reviewing test code quality\n- Improving test coverage strategy\n- Setting up testing infrastructure\n- Debugging flaky or slow tests\n\n## Rule Categories by Priority\n\n| Priority | Category | Impact | Prefix |\n|----------|----------|--------|--------|\n| 1 | Test Structure | CRITICAL | `struct-` |\n| 2 | Test Isolation | CRITICAL | `iso-` |\n| 3 | Assertions | HIGH | `assert-` |\n| 4 | Test Data | HIGH | `data-` |\n| 5 | Mocking | MEDIUM | `mock-` |\n| 6 | Coverage | MEDIUM | `cov-` |\n| 7 | Performance | LOW | `perf-` |\n\n## Quick Reference\n\n### 1. Test Structure (CRITICAL)\n\n- `struct-aaa-pattern` - Arrange, Act, Assert pattern\n- `struct-descriptive-names` - Descriptive test names\n- `struct-one-assertion` - One logical assertion per test\n- `struct-describe-it` - Organized test suites with describe/it\n- `struct-given-when-then` - BDD style when appropriate\n- `struct-setup-teardown` - Proper setup and teardown\n\n### 2. Test Isolation (CRITICAL)\n\n- `iso-independent-tests` - Tests run independently\n- `iso-no-shared-state` - No shared mutable state\n- `iso-deterministic` - Same result every run\n- `iso-no-order-dependency` - Run in any order\n- `iso-cleanup` - Clean up after tests\n- `iso-test-doubles` - Strategic use of test doubles\n\n### 3. Assertions (HIGH)\n\n- `assert-specific` - Use specific assertions\n- `assert-meaningful-messages` - Helpful failure messages\n- `assert-expected-actual` - Expected value first\n- `assert-no-magic-numbers` - Use named constants\n- `assert-custom-matchers` - Custom matchers for domain logic\n\n### 4. Test Data (HIGH)\n\n- `data-factories` - Use factories for test data\n- `data-builders` - Builder pattern for complex objects\n- `data-faker` - Generate realistic fake data\n- `data-minimal` - Minimal test data\n- `data-realistic` - Realistic edge cases\n- `data-fixtures` - Manage test fixtures\n\n### 5. Mocking (MEDIUM)\n\n- `mock-boundaries` - Mock only at boundaries\n- `mock-verify-interactions` - Verify important mock calls\n- `mock-minimal` - Don't over-mock\n- `mock-realistic` - Realistic mock behavior with MSW\n\n### 6. Coverage (MEDIUM)\n\n- `cov-meaningful` - Focus on meaningful coverage\n- `cov-edge-cases` - Cover edge cases and boundary values\n- `cov-unhappy-paths` - Test error scenarios\n- `cov-not-100-percent` - 100% coverage isn't the goal\n\n### 7. Performance (LOW)\n\n- `perf-fast-unit` - Keep unit tests fast (<50ms each)\n- `perf-parallel` - Run tests in parallel\n- `perf-test-organization` - Organize tests for fast feedback\n\n## Essential Guidelines\n\n### AAA Pattern (Arrange, Act, Assert)\n\n```typescript\nit('calculates total with discount', () => {\n  // Arrange\n  const cart = new ShoppingCart();\n  cart.addItem({ name: 'Book', price: 20 });\n  cart.applyDiscount(0.1);\n\n  // Act\n  const total = cart.getTotal();\n\n  // Assert\n  expect(total).toBe(18);\n});\n```\n\n### Descriptive Test Names\n\n```typescript\n// ✅ Describes behavior and scenario\ndescribe('UserService.register', () => {\n  it('creates user with hashed password', () => {});\n  it('throws ValidationError when email is invalid', () => {});\n  it('sends welcome email after successful registration', () => {});\n});\n```\n\n### Test Isolation\n\n```typescript\n// ✅ Each test sets up its own data\nbeforeEach(() => {\n  mockRepository = { save: vi.fn(), find: vi.fn() };\n  service = new OrderService(mockRepository);\n});\n```\n\n## How to Use\n\nRead individual rule files for detailed explanations:\n\n```\nrules/struct-aaa-pattern.md\nrules/iso-independent-tests.md\nrules/mock-boundaries.md\nrules/cov-meaningful.md\n```\n\n## References\n\n- [Vitest Documentation](https://vitest.dev)\n- [Jest Documentation](https://jestjs.io)\n- [Testing Library](https://testing-library.com)\n- [MSW (Mock Service Worker)](https://mswjs.io)\n\n## Full Compiled Document\n\nFor the complete guide with all rules expanded: `AGENTS.md`","tags":["testing","best","practices","agent","skills","asyrafhussin","agent-rules","agent-skills","ai-agents","ai-slop","claude-code","code-quality"],"capabilities":["skill","source-asyrafhussin","skill-testing-best-practices","topic-agent-rules","topic-agent-skills","topic-ai-agents","topic-ai-slop","topic-claude-code","topic-code-quality","topic-code-review","topic-codex","topic-cursor","topic-laravel","topic-nodejs","topic-react"],"categories":["agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/AsyrafHussin/agent-skills/testing-best-practices","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add AsyrafHussin/agent-skills","source_repo":"https://github.com/AsyrafHussin/agent-skills","install_from":"skills.sh"}},"qualityScore":"0.469","qualityRationale":"deterministic score 0.47 from registry signals: · indexed on github topic:agent-skills · 39 github stars · SKILL.md body (4,169 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:58:25.669Z","embedding":null,"createdAt":"2026-05-16T18:57:15.303Z","updatedAt":"2026-05-18T18:58:25.669Z","lastSeenAt":"2026-05-18T18:58:25.669Z","tsv":"'0.1':464 '1':115,148 '100':403,405 '18':473 '2':120,202 '2.0.0':68 '20':462 '3':125,254 '34':57,71 '4':129,294 '5':134,339 '50ms':422 '6':138,373 '7':60,74,142,411 'aaa':154,442 'across':59,73 'act':157,445,465 'actual':273 'agents.md':564 'appli':80 'appropri':193 'arrang':156,444,453 'assert':126,128,158,170,173,255,258,262,264,271,278,286,446,469 'assert-custom-match':285 'assert-expected-actu':270 'assert-meaningful-messag':263 'assert-no-magic-numb':277 'assert-specif':257 'bdd':190 'beforeeach':514 'behavior':370,479 'best':3,37,42 'book':460 'boundari':344,348,391 'builder':308,309 'calcul':449 'call':356 'cart':455 'cart.additem':458 'cart.applydiscount':463 'cart.gettotal':468 'case':332,386,389 'categori':61,75,108,112 'clean':241 'cleanup':240 'code':21,92 'compil':554 'complet':558 'complex':312 'const':454,466 'constant':284 'contain':56 'count':70 'cov':141,377,384,394,401 'cov-edge-cas':383 'cov-meaning':376 'cov-not':400 'cov-unhappy-path':393 'cover':387 'coverag':24,96,139,374,382,406 'creat':485 'critic':118,123,151,205 'custom':287,289 'data':131,133,296,299,305,307,315,320,322,326,328,334,513 'data-build':306 'data-factori':298 'data-fak':314 'data-fixtur':333 'data-minim':321 'data-realist':327 'debug':102 'depend':233 'describ':178,478,482 'describe/it':184 'descript':162,164,474 'detail':532 'determinist':224 'develop':13 'discount':452 'document':540,543,555 'domain':292 'doubl':248,253 'driven':12 'edg':331,385,388 'email':494,500 'error':398 'essenti':440 'everi':227 'expand':563 'expect':272,274,470 'explan':533 'factori':300,302 'failur':268 'fake':319 'faker':316 'fast':416,421,438 'feedback':439 'file':530 'find':518 'first':276 'fixtur':335,338 'flaki':103 'focus':379 'full':553 'generat':317 'given':187 'goal':410 'guid':559 'guidelin':83,441 'hash':488 'help':267 'high':127,132,256,297 'impact':113 'import':354 'improv':22,94 'independ':208,212 'individu':528 'infrastructur':101 'integr':7,46,88 'interact':352 'invalid':496 'isn':407 'iso':124,207,214,223,230,239,246 'iso-cleanup':238 'iso-determinist':222 'iso-independent-test':206 'iso-no-order-depend':229 'iso-no-shared-st':213 'iso-test-doubl':245 'isol':122,204,505 'jest':542 'jest/vitest':65 'jestjs.io':544 'keep':418 'librari':546 'licens':76 'logic':172,293 'low':144,413 'magic':280 'maintain':53 'manag':336 'matcher':288,290 'meaning':265,378,381 'medium':136,140,341,375 'messag':266,269 'metadata':66 'minim':323,324,359 'mit':77 'mock':135,137,340,343,345,350,355,358,364,366,369,549 'mock-boundari':342 'mock-minim':357 'mock-realist':365 'mock-verify-interact':349 'mockrepositori':515,523 'msw':372,548 'mswjs.io':552 'mutabl':220 'name':163,166,283,459,476 'new':456,521 'number':281 'object':313 'one':169,171 'order':232,237 'orderservic':522 'organ':180,434,435 'over-mock':362 'parallel':426,430 'password':489 'path':396 'pattern':155,159,310,443 'per':174 'percent':404 'perf':145,415,425,432 'perf-fast-unit':414 'perf-parallel':424 'perf-test-organ':431 'perform':143,412 'practic':4,38,43 'prefix':114 'price':461 'principl':14,50 'prioriti':110,111 'proper':198 'qualiti':93 'quick':146 'read':527 'realist':318,329,330,367,368 'refer':81,147,538 'registr':503 'reliabl':52 'result':226 'review':19,34,90 'rule':58,69,72,107,529,562 'rules/cov-meaningful.md':537 'rules/iso-independent-tests.md':535 'rules/mock-boundaries.md':536 'rules/struct-aaa-pattern.md':534 'run':211,228,234,427 'save':516 'scenario':399,481 'send':498 'servic':520,550 'set':26,98,509 'setup':196,199 'share':216,219 'shoppingcart':457 'skill' 'skill-testing-best-practices' 'slow':105 'source-asyrafhussin' 'specif':259,261 'state':217,221 'strateg':249 'strategi':29,97 'struct':119,153,161,168,177,186,195 'struct-aaa-pattern':152 'struct-describe-it':176 'struct-descriptive-nam':160 'struct-given-when-then':185 'struct-one-assert':167 'struct-setup-teardown':194 'structur':117,150 'style':191 'success':502 'suit':55,182 'tdd':40,49 'teardown':197,201 'test':2,6,8,11,18,20,23,28,33,35,36,41,45,47,54,89,91,95,100,106,116,121,130,149,165,175,181,203,209,210,244,247,252,295,304,325,337,397,420,428,433,436,475,504,508,545 'test-driven':10 'testing-best-practic':1 'testing-library.com':547 'throw':491 'tobe':472 'topic-agent-rules' 'topic-agent-skills' 'topic-ai-agents' 'topic-ai-slop' 'topic-claude-code' 'topic-code-quality' 'topic-code-review' 'topic-codex' 'topic-cursor' 'topic-laravel' 'topic-nodejs' 'topic-react' 'total':450,467,471 'trigger':30 'typescript':63,447,477,506 'unhappi':395 'unit':5,44,86,417,419 'use':15,62,250,260,282,301,526 'user':486 'userservice.register':483 'validationerror':492 'valu':275,392 'verifi':351,353 'version':67 'vi.fn':517,519 'vitest':539 'vitest.dev':541 'welcom':499 'worker':551 'write':17,32,85","prices":[{"id":"5be3859c-6f85-448e-8a68-024ee3d5f539","listingId":"1d4aba20-4d00-4233-961c-f0a5801f5331","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"AsyrafHussin","category":"agent-skills","install_from":"skills.sh"},"createdAt":"2026-05-16T18:57:15.303Z"}],"sources":[{"listingId":"1d4aba20-4d00-4233-961c-f0a5801f5331","source":"github","sourceId":"AsyrafHussin/agent-skills/testing-best-practices","sourceUrl":"https://github.com/AsyrafHussin/agent-skills/tree/main/skills/testing-best-practices","isPrimary":false,"firstSeenAt":"2026-05-16T18:57:15.303Z","lastSeenAt":"2026-05-18T18:58:25.669Z"}],"details":{"listingId":"1d4aba20-4d00-4233-961c-f0a5801f5331","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"AsyrafHussin","slug":"testing-best-practices","github":{"repo":"AsyrafHussin/agent-skills","stars":39,"topics":["agent-rules","agent-skills","ai-agents","ai-slop","claude-code","code-quality","code-review","codex","cursor","laravel","nodejs","react","technical-debt","typescript","windsurf"],"license":"mit","html_url":"https://github.com/AsyrafHussin/agent-skills","pushed_at":"2026-05-16T19:24:02Z","description":"Agent skills for AI coding agents (Claude Code, Cursor, Codex, Windsurf) — Laravel, React, TypeScript, MySQL, code quality, technical debt, documentation, and security.","skill_md_sha":"1ef2a1557bee7e874072278df6c541e3f1e43533","skill_md_path":"skills/testing-best-practices/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/AsyrafHussin/agent-skills/tree/main/skills/testing-best-practices"},"layout":"multi","source":"github","category":"agent-skills","frontmatter":{"name":"testing-best-practices","license":"MIT","description":"Unit testing, integration testing, and test-driven development principles. Use when writing tests, reviewing test code, improving test coverage, or setting up testing strategy. Triggers on \"write tests\", \"review tests\", \"testing best practices\", or \"TDD\"."},"skills_sh_url":"https://skills.sh/AsyrafHussin/agent-skills/testing-best-practices"},"updatedAt":"2026-05-18T18:58:25.669Z"}}