{"id":"c69b33ad-49a7-4c3f-b444-bce1442bf47a","shortId":"JZYVvD","kind":"skill","title":"vitest","tagline":"This skill should be used when the user asks to write, run, or debug tests with Vitest in TypeScript React/Next.js projects, or mentions unit/component tests, mocking, or testing utilities. Trigger phrases include \"write tests\", \"run tests\", \"mock functions\", \"test coverage\".","description":"# Your Role\n\nYou are an expert in writing tests with Vitest v4 for TypeScript React/Next.js projects. You help users write\nhigh-quality tests, debug failures, and maintain test suites efficiently.\n\n**Typical setup:**\n\n- Vitest v4 with jsdom environment\n- Globals enabled (`describe`, `test`, `expect`, `vi`)\n- Path aliases configured per project\n\n# Quick Start\n\n## Running Tests\n\n```bash\n# Run all unit tests\nnlx vitest run\n\n# Run tests matching pattern\nnlx vitest run tokens\n\n# Run specific test file\nnlx vitest run src/utils/format.test.ts\n\n# Run tests with matching name\nnlx vitest run -t \"adds token\"\n\n# Watch mode\nnlx vitest\n```\n\n## Writing Your First Test\n\n**File naming:** `*.test.ts` or `*.test.tsx`\n\n**Location:** Colocate with source files\n\n```typescript\nimport { describe, test, expect } from \"vitest\";\nimport { myFunction } from \"./my-function\";\n\ndescribe(\"myFunction\", () => {\n  test(\"returns expected value\", () => {\n    expect(myFunction(5)).toBe(10);\n  });\n});\n```\n\n# Project-Specific Patterns\n\n## Test Organization\n\nUse visual separators and descriptive blocks:\n\n```typescript\ndescribe(\"TokenStore\", () => {\n  /* ----------------------------------------------------------------\n   * Setup\n   * ------------------------------------------------------------- */\n\n  const validToken = { address: \"0x123\", symbol: \"TEST\" };\n\n  afterEach(() => {\n    // Reset state between tests\n    useTokensStore.getState().clearAll();\n  });\n\n  /* ----------------------------------------------------------------\n   * Adding tokens\n   * ------------------------------------------------------------- */\n\n  describe(\"addToken\", () => {\n    test(\"adds valid token and returns true\", () => {\n      const success = useTokensStore.getState().addToken(validToken);\n      expect(success).toBe(true);\n    });\n  });\n});\n```\n\n## Cleanup Pattern\n\nAlways reset state in `afterEach()`:\n\n```typescript\nimport { afterEach } from \"vitest\";\n\nafterEach(() => {\n  // Reset mocks\n  vi.clearAllMocks();\n\n  // Reset environment\n  process.env.NODE_ENV = originalEnv;\n\n  // Reset stores\n});\n```\n\n## Factory Mock Pattern\n\nPrefer factory functions for complex mocks:\n\n```typescript\n// __mocks__/localStorage.ts\nimport { vi } from \"vitest\";\n\nexport function createLocalStorageMock() {\n  const store = new Map<string, string>();\n\n  return {\n    getItem: vi.fn((key: string) => store.get(key) ?? null),\n    setItem: vi.fn((key: string, value: string) => {\n      store.set(key, value);\n    }),\n    removeItem: vi.fn((key: string) => {\n      store.delete(key);\n    }),\n    clear: vi.fn(() => {\n      store.clear();\n    })\n  };\n}\n\n// Usage in tests\nimport { createLocalStorageMock } from \"./__mocks__/localStorage\";\n\nconst mockStorage = createLocalStorageMock();\nglobal.localStorage = mockStorage as Storage;\n```\n\n## Shared Setup File\n\nGlobal mocks and configuration live in a setup file (e.g., `tests/setup.ts`):\n\n```typescript\nimport { vi } from \"vitest\";\n\n// Mock logger for all tests\nvi.mock(\"@/utils/logger\", () => ({\n  createLogger: vi.fn(() => ({\n    debug: vi.fn(),\n    info: vi.fn(),\n    warn: vi.fn(),\n    error: vi.fn()\n  }))\n}));\n```\n\n# Common Testing Scenarios\n\n## Testing Utilities\n\n```typescript\nimport { describe, test, expect, afterEach } from \"vitest\";\nimport { getEnvironment } from \"./environment\";\n\ndescribe(\"getEnvironment\", () => {\n  const originalEnv = process.env.NODE_ENV;\n\n  afterEach(() => {\n    process.env.NODE_ENV = originalEnv;\n  });\n\n  test(\"returns production when NODE_ENV is production\", () => {\n    process.env.NODE_ENV = \"production\";\n    expect(getEnvironment()).toBe(\"production\");\n  });\n\n  test(\"returns development by default\", () => {\n    process.env.NODE_ENV = undefined;\n    expect(getEnvironment()).toBe(\"development\");\n  });\n});\n```\n\n## Async Testing\n\n```typescript\ntest(\"async function resolves correctly\", async () => {\n  const result = await fetchData();\n  expect(result).toEqual({ data: \"value\" });\n});\n\ntest(\"async function rejects with error\", async () => {\n  await expect(failingFunction()).rejects.toThrow(\"Error message\");\n});\n```\n\n## Mocking\n\nFor function mocks (vi.fn, spyOn), module mocks (vi.mock, vi.doMock), and timer mocks (vi.useFakeTimers), see [references/mocking.md](references/mocking.md).\n\n# Debugging Failed Tests\n\n## Reading Test Output\n\nFocus on these signals:\n\n- **File and line number** - Where the failure occurred\n- **Expected vs. received** - What went wrong\n- **Stack trace** - Ignore framework internals, focus on your code\n\n## Common Failures\n\nFor known failure modes and how to recover (timeouts, async assertions, mock not called, snapshot drift, etc.), see [references/troubleshooting.md](references/troubleshooting.md).\n\n## Debugging Tools\n\n```bash\nnlx vitest --reporter=verbose   # Detailed output\nnlx vitest --ui                  # Visual debugging interface\nnlx vitest --coverage            # See what's tested\nnlx vitest --inspect             # Node debugger\nnlx vitest --run                 # Disable watch mode\n```\n\n# Best Practices\n\n## DO\n\n- Colocate tests with source files (`feature.ts` + `feature.test.ts`)\n- Use `describe` blocks to group related tests\n- Add `afterEach()` cleanup for state/mocks\n- Use visual separators for clarity (`/* --- */`)\n- Test behavior, not implementation\n- Use explicit type annotations for mocks\n- Keep tests focused and independent\n- Write tests before fixing bugs (reproduce the bug first)\n\n## DON'T\n\n- Test implementation details (internal variables)\n- Share state between tests\n- Mock everything (only mock boundaries: network, storage, time)\n- Forget to restore mocks/timers\n- Use `any` types in tests\n- Create brittle tests tied to DOM structure\n- Add backward-compatibility hacks for test utilities\n\n# Advanced Topics\n\nFor deeper dives, see the `./references/` directory:\n\n- **`testing-patterns.md`** - Complete pattern library (component tests, complex mocking, async patterns)\n- **`monorepo-testing.md`** - Workspace-specific strategies (shared vs. app tests, path aliases, organization)\n- **`troubleshooting.md`** - Debug guide (common errors, performance, coverage, CI/CD)\n\n# Coverage Analysis\n\nTo add coverage:\n\n```typescript\n// vitest.config.ts\nexport default defineConfig({\n  test: {\n    coverage: {\n      provider: \"v8\",\n      reporter: [\"text\", \"html\", \"json\"],\n      exclude: [\"**/*.test.ts\", \"**/__mocks__/**\", \"**/node_modules/**\"]\n    }\n  }\n});\n```\n\nRun with: `nlx vitest --coverage`\n\n# Configuration Reference\n\nExample config: `vitest.config.ts`\n\n```typescript\n{\n  environment: \"jsdom\",           // React/DOM APIs available\n  globals: true,                  // No imports needed for describe/test/expect\n  include: [\"**/*.test.{js,ts,tsx}\"],\n  exclude: [\"**/node_modules/**\", \"**/e2e/**\"],\n  setupFiles: [\"./tests/setup.ts\"],\n  alias: {\n    \"@\": \"./src\",\n    // Add your project's path aliases\n  },\n}\n```\n\n# Next Steps\n\n1. **For component testing** - See `./references/testing-patterns.md` (React Testing Library setup)\n2. **For monorepo-specific strategies** - See `./references/monorepo-testing.md`\n3. **For debugging help** - See `./references/troubleshooting.md`\n\nStart with simple unit tests, add component tests as needed.","tags":["vitest","agent","skills","paulrberg","agent-skills","ai-agents"],"capabilities":["skill","source-paulrberg","skill-vitest","topic-agent-skills","topic-ai-agents"],"categories":["agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/PaulRBerg/agent-skills/vitest","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add PaulRBerg/agent-skills","source_repo":"https://github.com/PaulRBerg/agent-skills","install_from":"skills.sh"}},"qualityScore":"0.478","qualityRationale":"deterministic score 0.48 from registry signals: · indexed on github topic:agent-skills · 56 github stars · SKILL.md body (7,137 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:57:37.173Z","embedding":null,"createdAt":"2026-04-22T12:56:37.487Z","updatedAt":"2026-05-18T18:57:37.173Z","lastSeenAt":"2026-05-18T18:57:37.173Z","tsv":"'/__mocks__':686 '/__mocks__/localstorage':299 '/e2e':718 '/environment':359 '/localstorage.ts':253 '/my-function':158 '/node_modules':687,717 '/references':634 '/references/monorepo-testing.md':748 '/references/testing-patterns.md':736 '/references/troubleshooting.md':754 '/src':722 '/tests/setup.ts':720 '/utils/logger':332 '0x123':189 '1':731 '10':169 '2':741 '3':749 '5':167 'ad':199 'add':128,204,550,619,669,723,760 'address':188 'addtoken':202,213 'advanc':627 'aftereach':192,225,228,231,353,366,551 'alia':721 'alias':87,656,728 'alway':221 'analysi':667 'annot':567 'api':702 'app':653 'ask':10 'assert':490 'async':397,401,405,416,421,489,644 'avail':703 'await':408,422 'backward':621 'backward-compat':620 'bash':95,502 'behavior':561 'best':533 'block':181,545 'boundari':599 'brittl':613 'bug':579,582 'call':493 'ci/cd':665 'clariti':559 'cleanup':219,552 'clear':290 'clearal':198 'code':477 'coloc':144,536 'common':343,478,661 'compat':622 'complet':637 'complex':249,642 'compon':640,733,761 'config':696 'configur':88,313,693 'const':186,210,261,300,362,406 'correct':404 'coverag':41,517,664,666,670,677,692 'creat':612 'createlocalstoragemock':260,297,302 'createlogg':333 'data':413 'debug':15,66,335,445,500,513,659,751 'debugg':526 'deeper':630 'default':389,674 'defineconfig':675 'describ':82,150,159,183,201,350,360,544 'describe/test/expect':710 'descript':180 'detail':507,588 'develop':387,396 'directori':635 'disabl':530 'dive':631 'dom':617 'drift':495 'e.g':319 'effici':72 'enabl':81 'env':238,365,368,375,379,391 'environ':79,236,699 'error':341,420,426,662 'etc':496 'everyth':596 'exampl':695 'exclud':684,716 'expect':84,152,163,165,215,352,381,393,410,423,463 'expert':47 'explicit':565 'export':258,673 'factori':242,246 'fail':446 'failingfunct':424 'failur':67,461,479,482 'feature.test.ts':542 'feature.ts':541 'fetchdata':409 'file':114,138,147,309,318,455,540 'first':136,583 'fix':578 'focus':451,474,572 'forget':603 'framework':472 'function':39,247,259,402,417,430 'getenviron':357,361,382,394 'getitem':268 'global':80,310,704 'global.localstorage':303 'group':547 'guid':660 'hack':623 'help':59,752 'high':63 'high-qual':62 'html':682 'ignor':471 'implement':563,587 'import':149,155,227,254,296,322,349,356,707 'includ':33,711 'independ':574 'info':337 'inspect':524 'interfac':514 'intern':473,589 'js':713 'jsdom':78,700 'json':683 'keep':570 'key':270,273,277,282,286,289 'known':481 'librari':639,739 'line':457 'live':314 'locat':143 'logger':327 'maintain':69 'map':264 'match':105,122 'mention':24 'messag':427 'mock':27,38,233,243,250,252,311,326,428,431,435,440,491,569,595,598,643 'mocks/timers':606 'mockstorag':301,304 'mode':131,483,532 'modul':434 'monorepo':744 'monorepo-specif':743 'monorepo-testing.md':646 'myfunct':156,160,166 'name':123,139 'need':708,764 'network':600 'new':263 'next':729 'nlx':100,107,115,124,132,503,509,515,522,527,690 'node':374,525 'null':274 'number':458 'occur':462 'organ':175,657 'originalenv':239,363,369 'output':450,508 'path':86,655,727 'pattern':106,173,220,244,638,645 'per':89 'perform':663 'phrase':32 'practic':534 'prefer':245 'process.env.node':237,364,367,378,390 'product':372,377,380,384 'project':22,57,90,171,725 'project-specif':170 'provid':678 'qualiti':64 'quick':91 'react':737 'react/dom':701 'react/next.js':21,56 'read':448 'receiv':465 'recov':487 'refer':694 'references/mocking.md':443,444 'references/troubleshooting.md':498,499 'reject':418 'rejects.tothrow':425 'relat':548 'removeitem':284 'report':505,680 'reproduc':580 'reset':193,222,232,235,240 'resolv':403 'restor':605 'result':407,411 'return':162,208,267,371,386 'role':43 'run':13,36,93,96,102,103,109,111,117,119,126,529,688 'scenario':345 'see':442,497,518,632,735,747,753 'separ':178,557 'setitem':275 'setup':74,185,308,317,740 'setupfil':719 'share':307,591,651 'signal':454 'simpl':757 'skill':3 'skill-vitest' 'snapshot':494 'sourc':146,539 'source-paulrberg' 'specif':112,172,649,745 'spyon':433 'src/utils/format.test.ts':118 'stack':469 'start':92,755 'state':194,223,592 'state/mocks':554 'step':730 'storag':306,601 'store':241,262 'store.clear':292 'store.delete':288 'store.get':272 'store.set':281 'strategi':650,746 'string':265,266,271,278,280,287 'structur':618 'success':211,216 'suit':71 'symbol':190 'test':16,26,29,35,37,40,50,65,70,83,94,99,104,113,120,137,151,161,174,191,196,203,295,330,344,346,351,370,385,398,400,415,447,449,521,537,549,560,571,576,586,594,611,614,625,641,654,676,712,734,738,759,762 'test.ts':140,685 'test.tsx':142 'testing-patterns.md':636 'tests/setup.ts':320 'text':681 'tie':615 'time':602 'timeout':488 'timer':439 'tobe':168,217,383,395 'toequal':412 'token':110,129,200,206 'tokenstor':184 'tool':501 'topic':628 'topic-agent-skills' 'topic-ai-agents' 'trace':470 'trigger':31 'troubleshooting.md':658 'true':209,218,705 'ts':714 'tsx':715 'type':566,609 'typescript':20,55,148,182,226,251,321,348,399,671,698 'typic':73 'ui':511 'undefin':392 'unit':98,758 'unit/component':25 'usag':293 'use':6,176,543,555,564,607 'user':9,60 'usetokensstore.getstate':197,212 'util':30,347,626 'v4':53,76 'v8':679 'valid':205 'validtoken':187,214 'valu':164,279,283,414 'variabl':590 'verbos':506 'vi':85,255,323 'vi.clearallmocks':234 'vi.domock':437 'vi.fn':269,276,285,291,334,336,338,340,342,432 'vi.mock':331,436 'vi.usefaketimers':441 'visual':177,512,556 'vitest':1,18,52,75,101,108,116,125,133,154,230,257,325,355,504,510,516,523,528,691 'vitest.config.ts':672,697 'vs':464,652 'warn':339 'watch':130,531 'went':467 'workspac':648 'workspace-specif':647 'write':12,34,49,61,134,575 'wrong':468","prices":[{"id":"c6724100-98a3-4185-833c-1d770446a60d","listingId":"c69b33ad-49a7-4c3f-b444-bce1442bf47a","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"PaulRBerg","category":"agent-skills","install_from":"skills.sh"},"createdAt":"2026-04-22T12:56:37.487Z"}],"sources":[{"listingId":"c69b33ad-49a7-4c3f-b444-bce1442bf47a","source":"github","sourceId":"PaulRBerg/agent-skills/vitest","sourceUrl":"https://github.com/PaulRBerg/agent-skills/tree/main/skills/vitest","isPrimary":false,"firstSeenAt":"2026-04-22T12:56:37.487Z","lastSeenAt":"2026-05-18T18:57:37.173Z"}],"details":{"listingId":"c69b33ad-49a7-4c3f-b444-bce1442bf47a","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"PaulRBerg","slug":"vitest","github":{"repo":"PaulRBerg/agent-skills","stars":56,"topics":["agent-skills","ai-agents"],"license":"mit","html_url":"https://github.com/PaulRBerg/agent-skills","pushed_at":"2026-05-17T10:33:19Z","description":"PRB's collection of agent skills","skill_md_sha":"3741366b3cfe0437040be7b10aa82c1f019d2dcd","skill_md_path":"skills/vitest/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/PaulRBerg/agent-skills/tree/main/skills/vitest"},"layout":"multi","source":"github","category":"agent-skills","frontmatter":{"name":"vitest","description":"This skill should be used when the user asks to write, run, or debug tests with Vitest in TypeScript React/Next.js projects, or mentions unit/component tests, mocking, or testing utilities. Trigger phrases include \"write tests\", \"run tests\", \"mock functions\", \"test coverage\"."},"skills_sh_url":"https://skills.sh/PaulRBerg/agent-skills/vitest"},"updatedAt":"2026-05-18T18:57:37.173Z"}}