[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ETSC7M7SYTZD8262PS6JP7":3,"skill-same:01M6ETSC7M7SYTZD8262PS6JP7":103},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":55,"linkOnly":56,"markdownContent":57,"markdownBody":58,"frontMatter":59,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":65,"ownerHtmlUrl":66,"ownerBlogUrl":6,"ownerDescription":67,"updatedAt":68,"install":69,"resources":82},"01M6ETSC7M7SYTZD8262PS6JP7","tdd-vitest-typescript",null,"Test-Driven Development (TDD) using Vitest and TypeScript. Use when the user requests help with TDD, writing tests before code, test-first development, Vitest test setup, TypeScript testing patterns, unit testing, integration testing, or following the Red-Green-Refactor cycle with Vitest.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Femz1998\u002Ftdd-vitest-typescript\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],"tdd vitest typescript","typescript","tdd","vitest","red-green-refactor","unit","integration testing","tests","green","cycle","patterns","unit testing","test setup","testing","use","testing patterns","refactor","code","development","writing","2026-11-10 10:12:30",false,"---\nname: tdd-vitest-typescript\ndescription: Test-Driven Development (TDD) using Vitest and TypeScript. Use when the user requests help with TDD, writing tests before code, test-first development, Vitest test setup, TypeScript testing patterns, unit testing, integration testing, or following the Red-Green-Refactor cycle with Vitest.\n---\n\n# TDD with Vitest and TypeScript\n\nGuide Claude through Test-Driven Development workflows using Vitest and TypeScript.\n\n## Core TDD Cycle: Red-Green-Refactor\n\nAlways follow this three-phase cycle:\n\n1. **Red**: Write a failing test that defines desired behavior\n2. **Green**: Write minimal code to make the test pass\n3. **Refactor**: Improve code quality while keeping tests green\n\n### Workflow Pattern\n\n```typescript\n\u002F\u002F 1. RED: Write the test first\ndescribe('Calculator', () => {\n  it('adds two numbers', () => {\n    const calc = new Calculator();\n    expect(calc.add(2, 3)).toBe(5);\n  });\n});\n\n\u002F\u002F Run test → Watch it fail (Red)\n\u002F\u002F 2. GREEN: Implement minimal code\nclass Calculator {\n  add(a: number, b: number): number {\n    return a + b;\n  }\n}\n\n\u002F\u002F Run test → Watch it pass (Green)\n\u002F\u002F 3. REFACTOR: Improve if needed while keeping tests green\n```\n\n## Vitest Setup and Configuration\n\n### Basic Vitest Config\n\nCreate `vitest.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vitest\u002Fconfig';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node', \u002F\u002F or 'jsdom' for DOM testing\n    coverage: {\n      provider: 'v8',\n      reporter: ['text', 'json', 'html'],\n    },\n  },\n});\n```\n\n### TypeScript Configuration\n\nEnsure `tsconfig.json` includes:\n\n```json\n{\n  \"compilerOptions\": {\n    \"types\": [\"vitest\u002Fglobals\"],\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n```\n\n## Test File Organization\n\n### Naming Conventions\n\n- Test files: `*.test.ts` or `*.spec.ts`\n- Place tests adjacent to source files or in `__tests__` directories\n- Match test file names to source files: `calculator.ts` → `calculator.test.ts`\n\n### Structure Pattern\n\n```typescript\nimport { describe, it, expect, beforeEach, afterEach } from 'vitest';\n\ndescribe('FeatureName', () => {\n  \u002F\u002F Setup\n  beforeEach(() => {\n    \u002F\u002F Runs before each test\n  });\n\n  afterEach(() => {\n    \u002F\u002F Cleanup after each test\n  });\n\n  describe('specific behavior', () => {\n    it('does something specific', () => {\n      \u002F\u002F Arrange\n      const input = setupTestData();\n      \n      \u002F\u002F Act\n      const result = performAction(input);\n      \n      \u002F\u002F Assert\n      expect(result).toBe(expected);\n    });\n  });\n});\n```\n\n## TypeScript Testing Patterns\n\n### Type-Safe Test Data\n\n```typescript\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nfunction createTestUser(overrides?: Partial\u003CUser>): User {\n  return {\n    id: 1,\n    name: 'Test User',\n    email: 'test@example.com',\n    ...overrides,\n  };\n}\n\nit('processes user data', () => {\n  const user = createTestUser({ name: 'Custom Name' });\n  expect(processUser(user)).toBeDefined();\n});\n```\n\n### Testing Generic Functions\n\n```typescript\ndescribe('generic array utilities', () => {\n  it('filters array by predicate', () => {\n    const numbers = [1, 2, 3, 4, 5];\n    const result = filter(numbers, (n: number) => n > 3);\n    expect(result).toEqual([4, 5]);\n  });\n});\n```\n\n### Testing Async\u002FPromise Code\n\n```typescript\ndescribe('async operations', () => {\n  it('fetches user data', async () => {\n    const user = await fetchUser(1);\n    expect(user.id).toBe(1);\n  });\n\n  it('handles errors', async () => {\n    await expect(fetchUser(-1)).rejects.toThrow('Invalid ID');\n  });\n});\n```\n\n## Mocking and Stubbing\n\n### Module Mocks\n\n```typescript\nimport { vi } from 'vitest';\nimport { fetchData } from '.\u002Fapi';\n\nvi.mock('.\u002Fapi');\n\ndescribe('data processing', () => {\n  it('processes fetched data', async () => {\n    vi.mocked(fetchData).mockResolvedValue({ data: 'test' });\n    \n    const result = await processData();\n    expect(result).toBe('processed: test');\n  });\n});\n```\n\n### Function Spies\n\n```typescript\ndescribe('event handling', () => {\n  it('calls callback on event', () => {\n    const callback = vi.fn();\n    const handler = new EventHandler(callback);\n    \n    handler.trigger('test-event');\n    \n    expect(callback).toHaveBeenCalledWith('test-event');\n    expect(callback).toHaveBeenCalledTimes(1);\n  });\n});\n```\n\n### Partial Mocks\n\n```typescript\nimport * as utils from '.\u002Futils';\n\nvi.spyOn(utils, 'helperFunction').mockReturnValue('mocked');\n\nit('uses mocked helper', () => {\n  const result = mainFunction();\n  expect(utils.helperFunction).toHaveBeenCalled();\n  expect(result).toContain('mocked');\n});\n```\n\n## Common Testing Patterns\n\n### Testing Classes\n\n```typescript\ndescribe('UserService', () => {\n  let service: UserService;\n  let mockRepository: MockRepository;\n\n  beforeEach(() => {\n    mockRepository = new MockRepository();\n    service = new UserService(mockRepository);\n  });\n\n  it('creates user with valid data', async () => {\n    const userData = { name: 'John', email: 'john@example.com' };\n    \n    const user = await service.createUser(userData);\n    \n    expect(user.id).toBeDefined();\n    expect(mockRepository.save).toHaveBeenCalledWith(\n      expect.objectContaining(userData)\n    );\n  });\n});\n```\n\n### Testing Pure Functions\n\n```typescript\ndescribe('pure utility functions', () => {\n  it('capitalizes first letter', () => {\n    expect(capitalize('hello')).toBe('Hello');\n    expect(capitalize('')).toBe('');\n    expect(capitalize('WORLD')).toBe('WORLD');\n  });\n});\n```\n\n### Testing Error Handling\n\n```typescript\ndescribe('error scenarios', () => {\n  it('throws on invalid input', () => {\n    expect(() => divide(10, 0)).toThrow('Division by zero');\n  });\n\n  it('returns error result', () => {\n    const result = parseJSON('invalid json');\n    expect(result.success).toBe(false);\n    expect(result.error).toBeDefined();\n  });\n});\n```\n\n### Parametric Tests\n\n```typescript\nimport { describe, it, expect } from 'vitest';\n\ndescribe.each([\n  { input: 2, expected: 4 },\n  { input: 3, expected: 9 },\n  { input: 4, expected: 16 },\n])('square function', ({ input, expected }) => {\n  it(`squares ${input} to ${expected}`, () => {\n    expect(square(input)).toBe(expected);\n  });\n});\n```\n\n## Test Coverage Guidelines\n\n### Running Coverage\n\n```bash\nvitest --coverage\n```\n\n### Coverage Targets\n\n- Aim for 80%+ coverage on business logic\n- 100% coverage on critical paths (authentication, payments, etc.)\n- Don't obsess over 100% everywhere—focus on meaningful tests\n\n### What to Test\n\n**Always test:**\n- Business logic and domain rules\n- Error handling and edge cases\n- Public APIs and interfaces\n- Data transformations\n\n**Consider skipping:**\n- Simple getters\u002Fsetters\n- Framework\u002Flibrary code\n- Trivial type definitions\n- Configuration files\n\n## TDD Best Practices\n\n### Write Tests First\n\nAlways start with the test, not the implementation:\n\n```typescript\n\u002F\u002F ❌ BAD: Writing implementation first\nclass Calculator {\n  add(a: number, b: number) { return a + b; }\n}\n\n\u002F\u002F ✅ GOOD: Test first\nit('adds two numbers', () => {\n  expect(new Calculator().add(2, 3)).toBe(5);\n});\n```\n\n### One Assertion Per Test\n\nKeep tests focused:\n\n```typescript\n\u002F\u002F ❌ BAD: Multiple concerns\nit('user operations', () => {\n  const user = createUser();\n  expect(user.id).toBeDefined();\n  expect(updateUser(user)).toBeTruthy();\n  expect(deleteUser(user.id)).toBeUndefined();\n});\n\n\u002F\u002F ✅ GOOD: Single concern\nit('creates user with ID', () => {\n  const user = createUser();\n  expect(user.id).toBeDefined();\n});\n\nit('updates existing user', () => {\n  const user = createUser();\n  expect(updateUser(user)).toBeTruthy();\n});\n```\n\n### Test Behavior, Not Implementation\n\n```typescript\n\u002F\u002F ❌ BAD: Testing implementation details\nit('calls internal helper method', () => {\n  const service = new Service();\n  const spy = vi.spyOn(service as any, '_internalHelper');\n  service.process();\n  expect(spy).toHaveBeenCalled();\n});\n\n\u002F\u002F ✅ GOOD: Testing behavior\nit('processes data correctly', () => {\n  const service = new Service();\n  const result = service.process(inputData);\n  expect(result).toEqual(expectedOutput);\n});\n```\n\n### Keep Tests Fast\n\n- Use mocks for external dependencies (databases, APIs, file system)\n- Avoid sleep\u002FsetTimeout in tests\n- Run expensive setup once with beforeAll when safe\n\n### Descriptive Test Names\n\n```typescript\n\u002F\u002F ❌ BAD: Vague\nit('works', () => { \u002F* ... *\u002F });\n\n\u002F\u002F ✅ GOOD: Descriptive\nit('returns empty array when no users match filter criteria', () => {\n  \u002F* ... *\u002F\n});\n```\n\n## Common TDD Workflow\n\n### Starting a New Feature\n\n1. Write a high-level test describing the feature:\n\n```typescript\ndescribe('User Registration', () => {\n  it('creates new user account with valid email', async () => {\n    const result = await registerUser({\n      email: 'new@example.com',\n      password: 'secure123',\n    });\n    \n    expect(result.success).toBe(true);\n    expect(result.user.email).toBe('new@example.com');\n  });\n});\n```\n\n2. Run test → See it fail (Red)\n3. Implement minimal code → See it pass (Green)\n4. Add edge case tests:\n\n```typescript\nit('rejects registration with existing email', async () => {\n  await registerUser({ email: 'existing@example.com', password: 'pass' });\n  \n  const result = await registerUser({\n    email: 'existing@example.com',\n    password: 'pass2',\n  });\n  \n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Email already registered');\n});\n\nit('rejects weak passwords', async () => {\n  const result = await registerUser({\n    email: 'new@example.com',\n    password: '123',\n  });\n  \n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Password too weak');\n});\n```\n\n5. Refactor implementation while keeping tests green\n\n### Debugging Failed Tests\n\nWhen tests fail unexpectedly:\n\n1. Check test isolation—are tests interfering with each other?\n2. Verify mocks are properly reset between tests\n3. Use `it.only()` to run single test\n4. Add console.log or debugger statements\n5. Check async timing issues\n\n## Integration Testing with Vitest\n\n### Testing Multiple Units Together\n\n```typescript\ndescribe('Order Processing Integration', () => {\n  let database: TestDatabase;\n  let paymentGateway: MockPaymentGateway;\n  let orderService: OrderService;\n\n  beforeEach(async () => {\n    database = await TestDatabase.create();\n    paymentGateway = new MockPaymentGateway();\n    orderService = new OrderService(database, paymentGateway);\n  });\n\n  afterEach(async () => {\n    await database.cleanup();\n  });\n\n  it('completes order flow from cart to confirmation', async () => {\n    const user = await database.createUser();\n    const cart = await orderService.createCart(user.id);\n    await orderService.addItem(cart.id, { productId: 1, quantity: 2 });\n    \n    paymentGateway.simulateSuccess();\n    const order = await orderService.checkout(cart.id);\n    \n    expect(order.status).toBe('confirmed');\n    expect(order.items).toHaveLength(1);\n  });\n});\n```\n\n## Watch Mode\n\nVitest runs in watch mode by default during development:\n\n```bash\nvitest\n```\n\nThis automatically re-runs tests when files change, enabling rapid TDD cycles.\n\n## Quick Reference: Common Matchers\n\n```typescript\n\u002F\u002F Equality\nexpect(value).toBe(5);                    \u002F\u002F Strict equality (===)\nexpect(value).toEqual({ a: 1 });          \u002F\u002F Deep equality\n\n\u002F\u002F Truthiness\nexpect(value).toBeTruthy();\nexpect(value).toBeFalsy();\nexpect(value).toBeNull();\nexpect(value).toBeUndefined();\nexpect(value).toBeDefined();\n\n\u002F\u002F Numbers\nexpect(value).toBeGreaterThan(3);\nexpect(value).toBeLessThan(10);\nexpect(value).toBeCloseTo(0.3);           \u002F\u002F Floating point\n\n\u002F\u002F Strings\nexpect(string).toMatch(\u002Fpattern\u002F);\nexpect(string).toContain('substring');\n\n\u002F\u002F Arrays\nexpect(array).toContain(item);\nexpect(array).toHaveLength(3);\n\n\u002F\u002F Objects\nexpect(object).toHaveProperty('key');\nexpect(object).toMatchObject({ a: 1 });   \u002F\u002F Partial match\n\n\u002F\u002F Exceptions\nexpect(() => fn()).toThrow();\nexpect(() => fn()).toThrow('Error message');\nexpect(async () => fn()).rejects.toThrow();\n\n\u002F\u002F Functions\nexpect(fn).toHaveBeenCalled();\nexpect(fn).toHaveBeenCalledWith(arg1, arg2);\nexpect(fn).toHaveBeenCalledTimes(2);\n```\n\n## Tips for Effective TDD\n\n1. **Start simple**: Begin with the simplest test case, not the most complex\n2. **Take small steps**: Write one test, make it pass, refactor, repeat\n3. **Trust the process**: Resist urge to write implementation before tests\n4. **Refactor fearlessly**: With good test coverage, refactoring is safe\n5. **Keep tests maintainable**: Tests are code too—keep them clean and DRY\n6. **Run tests frequently**: Vitest's watch mode makes this effortless\n7. **Write tests for bugs**: When you find a bug, write a test that exposes it first\n\n## When to Use This Skill\n\nApply TDD when:\n- Building new features from scratch\n- Fixing bugs (write failing test first)\n- Refactoring existing code\n- Learning a new API or library\n- Working on critical business logic\n\nTDD is especially valuable for:\n- Pure functions and algorithms\n- Business logic and domain models\n- Data transformations\n- API endpoints and services\n","# TDD with Vitest and TypeScript\n\nGuide Claude through Test-Driven Development workflows using Vitest and TypeScript.\n\n## Core TDD Cycle: Red-Green-Refactor\n\nAlways follow this three-phase cycle:\n\n1. **Red**: Write a failing test that defines desired behavior\n2. **Green**: Write minimal code to make the test pass\n3. **Refactor**: Improve code quality while keeping tests green\n\n### Workflow Pattern\n\n```typescript\n\u002F\u002F 1. RED: Write the test first\ndescribe('Calculator', () => {\n  it('adds two numbers', () => {\n    const calc = new Calculator();\n    expect(calc.add(2, 3)).toBe(5);\n  });\n});\n\n\u002F\u002F Run test → Watch it fail (Red)\n\u002F\u002F 2. GREEN: Implement minimal code\nclass Calculator {\n  add(a: number, b: number): number {\n    return a + b;\n  }\n}\n\n\u002F\u002F Run test → Watch it pass (Green)\n\u002F\u002F 3. REFACTOR: Improve if needed while keeping tests green\n```\n\n## Vitest Setup and Configuration\n\n### Basic Vitest Config\n\nCreate `vitest.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vitest\u002Fconfig';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node', \u002F\u002F or 'jsdom' for DOM testing\n    coverage: {\n      provider: 'v8',\n      reporter: ['text', 'json', 'html'],\n    },\n  },\n});\n```\n\n### TypeScript Configuration\n\nEnsure `tsconfig.json` includes:\n\n```json\n{\n  \"compilerOptions\": {\n    \"types\": [\"vitest\u002Fglobals\"],\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n```\n\n## Test File Organization\n\n### Naming Conventions\n\n- Test files: `*.test.ts` or `*.spec.ts`\n- Place tests adjacent to source files or in `__tests__` directories\n- Match test file names to source files: `calculator.ts` → `calculator.test.ts`\n\n### Structure Pattern\n\n```typescript\nimport { describe, it, expect, beforeEach, afterEach } from 'vitest';\n\ndescribe('FeatureName', () => {\n  \u002F\u002F Setup\n  beforeEach(() => {\n    \u002F\u002F Runs before each test\n  });\n\n  afterEach(() => {\n    \u002F\u002F Cleanup after each test\n  });\n\n  describe('specific behavior', () => {\n    it('does something specific', () => {\n      \u002F\u002F Arrange\n      const input = setupTestData();\n      \n      \u002F\u002F Act\n      const result = performAction(input);\n      \n      \u002F\u002F Assert\n      expect(result).toBe(expected);\n    });\n  });\n});\n```\n\n## TypeScript Testing Patterns\n\n### Type-Safe Test Data\n\n```typescript\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nfunction createTestUser(overrides?: Partial\u003CUser>): User {\n  return {\n    id: 1,\n    name: 'Test User',\n    email: 'test@example.com',\n    ...overrides,\n  };\n}\n\nit('processes user data', () => {\n  const user = createTestUser({ name: 'Custom Name' });\n  expect(processUser(user)).toBeDefined();\n});\n```\n\n### Testing Generic Functions\n\n```typescript\ndescribe('generic array utilities', () => {\n  it('filters array by predicate', () => {\n    const numbers = [1, 2, 3, 4, 5];\n    const result = filter(numbers, (n: number) => n > 3);\n    expect(result).toEqual([4, 5]);\n  });\n});\n```\n\n### Testing Async\u002FPromise Code\n\n```typescript\ndescribe('async operations', () => {\n  it('fetches user data', async () => {\n    const user = await fetchUser(1);\n    expect(user.id).toBe(1);\n  });\n\n  it('handles errors', async () => {\n    await expect(fetchUser(-1)).rejects.toThrow('Invalid ID');\n  });\n});\n```\n\n## Mocking and Stubbing\n\n### Module Mocks\n\n```typescript\nimport { vi } from 'vitest';\nimport { fetchData } from '.\u002Fapi';\n\nvi.mock('.\u002Fapi');\n\ndescribe('data processing', () => {\n  it('processes fetched data', async () => {\n    vi.mocked(fetchData).mockResolvedValue({ data: 'test' });\n    \n    const result = await processData();\n    expect(result).toBe('processed: test');\n  });\n});\n```\n\n### Function Spies\n\n```typescript\ndescribe('event handling', () => {\n  it('calls callback on event', () => {\n    const callback = vi.fn();\n    const handler = new EventHandler(callback);\n    \n    handler.trigger('test-event');\n    \n    expect(callback).toHaveBeenCalledWith('test-event');\n    expect(callback).toHaveBeenCalledTimes(1);\n  });\n});\n```\n\n### Partial Mocks\n\n```typescript\nimport * as utils from '.\u002Futils';\n\nvi.spyOn(utils, 'helperFunction').mockReturnValue('mocked');\n\nit('uses mocked helper', () => {\n  const result = mainFunction();\n  expect(utils.helperFunction).toHaveBeenCalled();\n  expect(result).toContain('mocked');\n});\n```\n\n## Common Testing Patterns\n\n### Testing Classes\n\n```typescript\ndescribe('UserService', () => {\n  let service: UserService;\n  let mockRepository: MockRepository;\n\n  beforeEach(() => {\n    mockRepository = new MockRepository();\n    service = new UserService(mockRepository);\n  });\n\n  it('creates user with valid data', async () => {\n    const userData = { name: 'John', email: 'john@example.com' };\n    \n    const user = await service.createUser(userData);\n    \n    expect(user.id).toBeDefined();\n    expect(mockRepository.save).toHaveBeenCalledWith(\n      expect.objectContaining(userData)\n    );\n  });\n});\n```\n\n### Testing Pure Functions\n\n```typescript\ndescribe('pure utility functions', () => {\n  it('capitalizes first letter', () => {\n    expect(capitalize('hello')).toBe('Hello');\n    expect(capitalize('')).toBe('');\n    expect(capitalize('WORLD')).toBe('WORLD');\n  });\n});\n```\n\n### Testing Error Handling\n\n```typescript\ndescribe('error scenarios', () => {\n  it('throws on invalid input', () => {\n    expect(() => divide(10, 0)).toThrow('Division by zero');\n  });\n\n  it('returns error result', () => {\n    const result = parseJSON('invalid json');\n    expect(result.success).toBe(false);\n    expect(result.error).toBeDefined();\n  });\n});\n```\n\n### Parametric Tests\n\n```typescript\nimport { describe, it, expect } from 'vitest';\n\ndescribe.each([\n  { input: 2, expected: 4 },\n  { input: 3, expected: 9 },\n  { input: 4, expected: 16 },\n])('square function', ({ input, expected }) => {\n  it(`squares ${input} to ${expected}`, () => {\n    expect(square(input)).toBe(expected);\n  });\n});\n```\n\n## Test Coverage Guidelines\n\n### Running Coverage\n\n```bash\nvitest --coverage\n```\n\n### Coverage Targets\n\n- Aim for 80%+ coverage on business logic\n- 100% coverage on critical paths (authentication, payments, etc.)\n- Don't obsess over 100% everywhere—focus on meaningful tests\n\n### What to Test\n\n**Always test:**\n- Business logic and domain rules\n- Error handling and edge cases\n- Public APIs and interfaces\n- Data transformations\n\n**Consider skipping:**\n- Simple getters\u002Fsetters\n- Framework\u002Flibrary code\n- Trivial type definitions\n- Configuration files\n\n## TDD Best Practices\n\n### Write Tests First\n\nAlways start with the test, not the implementation:\n\n```typescript\n\u002F\u002F ❌ BAD: Writing implementation first\nclass Calculator {\n  add(a: number, b: number) { return a + b; }\n}\n\n\u002F\u002F ✅ GOOD: Test first\nit('adds two numbers', () => {\n  expect(new Calculator().add(2, 3)).toBe(5);\n});\n```\n\n### One Assertion Per Test\n\nKeep tests focused:\n\n```typescript\n\u002F\u002F ❌ BAD: Multiple concerns\nit('user operations', () => {\n  const user = createUser();\n  expect(user.id).toBeDefined();\n  expect(updateUser(user)).toBeTruthy();\n  expect(deleteUser(user.id)).toBeUndefined();\n});\n\n\u002F\u002F ✅ GOOD: Single concern\nit('creates user with ID', () => {\n  const user = createUser();\n  expect(user.id).toBeDefined();\n});\n\nit('updates existing user', () => {\n  const user = createUser();\n  expect(updateUser(user)).toBeTruthy();\n});\n```\n\n### Test Behavior, Not Implementation\n\n```typescript\n\u002F\u002F ❌ BAD: Testing implementation details\nit('calls internal helper method', () => {\n  const service = new Service();\n  const spy = vi.spyOn(service as any, '_internalHelper');\n  service.process();\n  expect(spy).toHaveBeenCalled();\n});\n\n\u002F\u002F ✅ GOOD: Testing behavior\nit('processes data correctly', () => {\n  const service = new Service();\n  const result = service.process(inputData);\n  expect(result).toEqual(expectedOutput);\n});\n```\n\n### Keep Tests Fast\n\n- Use mocks for external dependencies (databases, APIs, file system)\n- Avoid sleep\u002FsetTimeout in tests\n- Run expensive setup once with beforeAll when safe\n\n### Descriptive Test Names\n\n```typescript\n\u002F\u002F ❌ BAD: Vague\nit('works', () => { \u002F* ... *\u002F });\n\n\u002F\u002F ✅ GOOD: Descriptive\nit('returns empty array when no users match filter criteria', () => {\n  \u002F* ... *\u002F\n});\n```\n\n## Common TDD Workflow\n\n### Starting a New Feature\n\n1. Write a high-level test describing the feature:\n\n```typescript\ndescribe('User Registration', () => {\n  it('creates new user account with valid email', async () => {\n    const result = await registerUser({\n      email: 'new@example.com',\n      password: 'secure123',\n    });\n    \n    expect(result.success).toBe(true);\n    expect(result.user.email).toBe('new@example.com');\n  });\n});\n```\n\n2. Run test → See it fail (Red)\n3. Implement minimal code → See it pass (Green)\n4. Add edge case tests:\n\n```typescript\nit('rejects registration with existing email', async () => {\n  await registerUser({ email: 'existing@example.com', password: 'pass' });\n  \n  const result = await registerUser({\n    email: 'existing@example.com',\n    password: 'pass2',\n  });\n  \n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Email already registered');\n});\n\nit('rejects weak passwords', async () => {\n  const result = await registerUser({\n    email: 'new@example.com',\n    password: '123',\n  });\n  \n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Password too weak');\n});\n```\n\n5. Refactor implementation while keeping tests green\n\n### Debugging Failed Tests\n\nWhen tests fail unexpectedly:\n\n1. Check test isolation—are tests interfering with each other?\n2. Verify mocks are properly reset between tests\n3. Use `it.only()` to run single test\n4. Add console.log or debugger statements\n5. Check async timing issues\n\n## Integration Testing with Vitest\n\n### Testing Multiple Units Together\n\n```typescript\ndescribe('Order Processing Integration', () => {\n  let database: TestDatabase;\n  let paymentGateway: MockPaymentGateway;\n  let orderService: OrderService;\n\n  beforeEach(async () => {\n    database = await TestDatabase.create();\n    paymentGateway = new MockPaymentGateway();\n    orderService = new OrderService(database, paymentGateway);\n  });\n\n  afterEach(async () => {\n    await database.cleanup();\n  });\n\n  it('completes order flow from cart to confirmation', async () => {\n    const user = await database.createUser();\n    const cart = await orderService.createCart(user.id);\n    await orderService.addItem(cart.id, { productId: 1, quantity: 2 });\n    \n    paymentGateway.simulateSuccess();\n    const order = await orderService.checkout(cart.id);\n    \n    expect(order.status).toBe('confirmed');\n    expect(order.items).toHaveLength(1);\n  });\n});\n```\n\n## Watch Mode\n\nVitest runs in watch mode by default during development:\n\n```bash\nvitest\n```\n\nThis automatically re-runs tests when files change, enabling rapid TDD cycles.\n\n## Quick Reference: Common Matchers\n\n```typescript\n\u002F\u002F Equality\nexpect(value).toBe(5);                    \u002F\u002F Strict equality (===)\nexpect(value).toEqual({ a: 1 });          \u002F\u002F Deep equality\n\n\u002F\u002F Truthiness\nexpect(value).toBeTruthy();\nexpect(value).toBeFalsy();\nexpect(value).toBeNull();\nexpect(value).toBeUndefined();\nexpect(value).toBeDefined();\n\n\u002F\u002F Numbers\nexpect(value).toBeGreaterThan(3);\nexpect(value).toBeLessThan(10);\nexpect(value).toBeCloseTo(0.3);           \u002F\u002F Floating point\n\n\u002F\u002F Strings\nexpect(string).toMatch(\u002Fpattern\u002F);\nexpect(string).toContain('substring');\n\n\u002F\u002F Arrays\nexpect(array).toContain(item);\nexpect(array).toHaveLength(3);\n\n\u002F\u002F Objects\nexpect(object).toHaveProperty('key');\nexpect(object).toMatchObject({ a: 1 });   \u002F\u002F Partial match\n\n\u002F\u002F Exceptions\nexpect(() => fn()).toThrow();\nexpect(() => fn()).toThrow('Error message');\nexpect(async () => fn()).rejects.toThrow();\n\n\u002F\u002F Functions\nexpect(fn).toHaveBeenCalled();\nexpect(fn).toHaveBeenCalledWith(arg1, arg2);\nexpect(fn).toHaveBeenCalledTimes(2);\n```\n\n## Tips for Effective TDD\n\n1. **Start simple**: Begin with the simplest test case, not the most complex\n2. **Take small steps**: Write one test, make it pass, refactor, repeat\n3. **Trust the process**: Resist urge to write implementation before tests\n4. **Refactor fearlessly**: With good test coverage, refactoring is safe\n5. **Keep tests maintainable**: Tests are code too—keep them clean and DRY\n6. **Run tests frequently**: Vitest's watch mode makes this effortless\n7. **Write tests for bugs**: When you find a bug, write a test that exposes it first\n\n## When to Use This Skill\n\nApply TDD when:\n- Building new features from scratch\n- Fixing bugs (write failing test first)\n- Refactoring existing code\n- Learning a new API or library\n- Working on critical business logic\n\nTDD is especially valuable for:\n- Pure functions and algorithms\n- Business logic and domain models\n- Data transformations\n- API endpoints and services\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Femz1998\u002Ftdd-vitest-typescript",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":70,"prompt":80,"zipAvailable":81},[71,74,77],{"tool":72,"command":73},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill tdd-vitest-typescript",{"tool":75,"command":76},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill tdd-vitest-typescript",{"tool":78,"command":79},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill tdd-vitest-typescript","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Femz1998\u002Ftdd-vitest-typescript\u002FSKILL.md",true,[83,89,93,99],{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"references\u002Fadvanced-patterns.md","REFERENCE","参考文档",13453,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Femz1998\u002Ftdd-vitest-typescript\u002Freferences\u002Fadvanced-patterns.md",{"path":90,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":91,"sourceHtmlUrl":92},"references\u002Fanti-patterns.md",12880,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Femz1998\u002Ftdd-vitest-typescript\u002Freferences\u002Fanti-patterns.md",{"path":94,"resourceType":95,"resourceTypeDesc":96,"sizeBytes":97,"sourceHtmlUrl":98},"scripts\u002Fsetup-vitest.js","SCRIPT","脚本",5562,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Femz1998\u002Ftdd-vitest-typescript\u002Fscripts\u002Fsetup-vitest.js",{"path":100,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":101,"sourceHtmlUrl":102},"skill-report.json",13215,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Femz1998\u002Ftdd-vitest-typescript\u002Fskill-report.json",[104,114,124,133,139,146],{"skillNo":105,"name":106,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":110,"publishedAt":55},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[109],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[111,112,113],"model","model hierarchy","model hierarchy skill",{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":120,"publishedAt":55},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[119],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[121,122,123],"MCP","zoom","zoom mcp",{"skillNo":125,"name":126,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":129,"publishedAt":55},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[130,131,132,122],"sdk","zoom apps sdk","apps",{"skillNo":134,"name":135,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":138,"publishedAt":55},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[135],{"skillNo":140,"name":141,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":145,"publishedAt":55},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[144],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[141],{"skillNo":147,"name":148,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":151,"publishedAt":55},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[148]]