[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EP9412ZY2DPZX03HBRSMJG":3,"skill-same:01M6EP9412ZY2DPZX03HBRSMJG":94},{"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":23,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":52,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":54,"updatedAt":55,"install":56,"resources":69},"01M6EP9412ZY2DPZX03HBRSMJG","designing-tests",null,"Designs and implements testing strategies for any codebase. Use when adding tests, improving coverage, setting up testing infrastructure, debugging test failures, or when asked about unit tests, integration tests, or E2E testing.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcloudai-x\u002Fdesigning-tests\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"designing tests","tests","coverage","testing strategies","unit","strategies","up","testing infrastructure","use","testing","e2e","integration","debugging","infrastructure","unit tests","integration tests","test","e2e testing","2026-11-10 10:12:30",false,"---\nname: designing-tests\ndescription: Designs and implements testing strategies for any codebase. Use when adding tests, improving coverage, setting up testing infrastructure, debugging test failures, or when asked about unit tests, integration tests, or E2E testing.\n---\n\n# Designing Tests\n\n## Test Implementation Workflow\n\nCopy this checklist and track progress:\n\n```\nTest Implementation Progress:\n- [ ] Step 1: Identify what to test\n- [ ] Step 2: Select appropriate test type\n- [ ] Step 3: Write tests following templates\n- [ ] Step 4: Run tests and verify passing\n- [ ] Step 5: Check coverage meets targets\n- [ ] Step 6: Fix any failing tests\n```\n\n## Testing Pyramid\n\nApply the testing pyramid for balanced coverage:\n\n```\n        \u002F\\\n       \u002F  \\     E2E Tests (10%)\n      \u002F----\\    - Critical user journeys\n     \u002F      \\   - Slow but comprehensive\n    \u002F--------\\  Integration Tests (20%)\n   \u002F          \\ - Component interactions\n  \u002F------------\\ - API contracts\n \u002F              \\ Unit Tests (70%)\n\u002F________________\\ - Fast, isolated\n                   - Business logic focus\n```\n\n## Framework Selection\n\n### JavaScript\u002FTypeScript\n| Type | Recommended | Alternative |\n|------|-------------|-------------|\n| Unit | Vitest | Jest |\n| Integration | Vitest + MSW | Jest + SuperTest |\n| E2E | Playwright | Cypress |\n| Component | Testing Library | Enzyme |\n\n### Python\n| Type | Recommended | Alternative |\n|------|-------------|-------------|\n| Unit | pytest | unittest |\n| Integration | pytest + httpx | pytest + requests |\n| E2E | Playwright | Selenium |\n| API | pytest + FastAPI TestClient | - |\n\n### Go\n| Type | Recommended |\n|------|-------------|\n| Unit | testing + testify |\n| Integration | testing + httptest |\n| E2E | testing + chromedp |\n\n## Test Structure Templates\n\n### Unit Test\n```javascript\ndescribe('[Unit] ComponentName', () => {\n  describe('methodName', () => {\n    it('should [expected behavior] when [condition]', () => {\n      \u002F\u002F Arrange\n      const input = createTestInput();\n\n      \u002F\u002F Act\n      const result = methodName(input);\n\n      \u002F\u002F Assert\n      expect(result).toEqual(expectedOutput);\n    });\n\n    it('should throw error when [invalid condition]', () => {\n      expect(() => methodName(invalidInput)).toThrow(ExpectedError);\n    });\n  });\n});\n```\n\n### Integration Test\n```javascript\ndescribe('[Integration] API \u002Fusers', () => {\n  beforeAll(async () => {\n    await setupTestDatabase();\n  });\n\n  afterAll(async () => {\n    await teardownTestDatabase();\n  });\n\n  it('should create user and return 201', async () => {\n    const response = await request(app)\n      .post('\u002Fusers')\n      .send({ name: 'Test', email: 'test@example.com' });\n\n    expect(response.status).toBe(201);\n    expect(response.body.id).toBeDefined();\n  });\n});\n```\n\n### E2E Test\n```javascript\ndescribe('[E2E] User Registration Flow', () => {\n  it('should complete registration successfully', async ({ page }) => {\n    await page.goto('\u002Fregister');\n\n    await page.fill('[data-testid=\"email\"]', 'new@example.com');\n    await page.fill('[data-testid=\"password\"]', 'SecurePass123!');\n    await page.click('[data-testid=\"submit\"]');\n\n    await expect(page.locator('.welcome-message')).toBeVisible();\n    await expect(page).toHaveURL('\u002Fdashboard');\n  });\n});\n```\n\n## Coverage Strategy\n\n### What to Cover\n- ✅ Business logic (100%)\n- ✅ Edge cases and error handling (90%+)\n- ✅ API contracts (100%)\n- ✅ Critical user paths (E2E)\n- ⚠️ UI components (snapshot + interaction)\n- ❌ Third-party library internals\n- ❌ Simple getters\u002Fsetters\n\n### Coverage Thresholds\n```json\n{\n  \"coverageThreshold\": {\n    \"global\": {\n      \"branches\": 80,\n      \"functions\": 80,\n      \"lines\": 80,\n      \"statements\": 80\n    },\n    \"src\u002Fcore\u002F\": {\n      \"branches\": 95,\n      \"functions\": 95\n    }\n  }\n}\n```\n\n## Test Data Management\n\n### Factories\u002FBuilders\n```javascript\n\u002F\u002F factories\u002Fuser.js\nexport const userFactory = (overrides = {}) => ({\n  id: faker.string.uuid(),\n  name: faker.person.fullName(),\n  email: faker.internet.email(),\n  createdAt: new Date(),\n  ...overrides,\n});\n\n\u002F\u002F Usage\nconst admin = userFactory({ role: 'admin' });\n```\n\n### Fixtures\n```javascript\n\u002F\u002F fixtures\u002Fusers.json\n{\n  \"validUser\": { \"name\": \"Test\", \"email\": \"test@example.com\" },\n  \"invalidUser\": { \"name\": \"\", \"email\": \"invalid\" }\n}\n```\n\n## Mocking Strategy\n\n### When to Mock\n- ✅ External APIs and services\n- ✅ Database in unit tests\n- ✅ Time\u002FDate for determinism\n- ✅ Random values\n- ❌ Internal modules (usually)\n- ❌ The code under test\n\n### Mock Examples\n```javascript\n\u002F\u002F API mocking with MSW\nimport { http, HttpResponse } from 'msw';\n\nexport const handlers = [\n  http.get('\u002Fapi\u002Fusers', () => {\n    return HttpResponse.json([\n      { id: 1, name: 'John' },\n    ]);\n  }),\n];\n\n\u002F\u002F Time mocking\nvi.useFakeTimers();\nvi.setSystemTime(new Date('2024-01-01'));\n```\n\n## Test Validation Loop\n\nAfter writing tests, run this validation:\n\n```\nTest Validation:\n- [ ] All tests pass: `npm test`\n- [ ] Coverage meets thresholds: `npm test -- --coverage`\n- [ ] No flaky tests (run multiple times)\n- [ ] Tests are independent (order doesn't matter)\n- [ ] Test names clearly describe behavior\n```\n\nIf any tests fail, fix them before proceeding. If coverage is below target, add more tests for uncovered code paths.\n\n```bash\n# Run tests\nnpm test\n\n# Run with coverage\nnpm test -- --coverage\n\n# Run specific test file\nnpm test -- path\u002Fto\u002Ftest.spec.ts\n\n# Run in watch mode during development\nnpm test -- --watch\n```\n","# Designing Tests\n\n## Test Implementation Workflow\n\nCopy this checklist and track progress:\n\n```\nTest Implementation Progress:\n- [ ] Step 1: Identify what to test\n- [ ] Step 2: Select appropriate test type\n- [ ] Step 3: Write tests following templates\n- [ ] Step 4: Run tests and verify passing\n- [ ] Step 5: Check coverage meets targets\n- [ ] Step 6: Fix any failing tests\n```\n\n## Testing Pyramid\n\nApply the testing pyramid for balanced coverage:\n\n```\n        \u002F\\\n       \u002F  \\     E2E Tests (10%)\n      \u002F----\\    - Critical user journeys\n     \u002F      \\   - Slow but comprehensive\n    \u002F--------\\  Integration Tests (20%)\n   \u002F          \\ - Component interactions\n  \u002F------------\\ - API contracts\n \u002F              \\ Unit Tests (70%)\n\u002F________________\\ - Fast, isolated\n                   - Business logic focus\n```\n\n## Framework Selection\n\n### JavaScript\u002FTypeScript\n| Type | Recommended | Alternative |\n|------|-------------|-------------|\n| Unit | Vitest | Jest |\n| Integration | Vitest + MSW | Jest + SuperTest |\n| E2E | Playwright | Cypress |\n| Component | Testing Library | Enzyme |\n\n### Python\n| Type | Recommended | Alternative |\n|------|-------------|-------------|\n| Unit | pytest | unittest |\n| Integration | pytest + httpx | pytest + requests |\n| E2E | Playwright | Selenium |\n| API | pytest + FastAPI TestClient | - |\n\n### Go\n| Type | Recommended |\n|------|-------------|\n| Unit | testing + testify |\n| Integration | testing + httptest |\n| E2E | testing + chromedp |\n\n## Test Structure Templates\n\n### Unit Test\n```javascript\ndescribe('[Unit] ComponentName', () => {\n  describe('methodName', () => {\n    it('should [expected behavior] when [condition]', () => {\n      \u002F\u002F Arrange\n      const input = createTestInput();\n\n      \u002F\u002F Act\n      const result = methodName(input);\n\n      \u002F\u002F Assert\n      expect(result).toEqual(expectedOutput);\n    });\n\n    it('should throw error when [invalid condition]', () => {\n      expect(() => methodName(invalidInput)).toThrow(ExpectedError);\n    });\n  });\n});\n```\n\n### Integration Test\n```javascript\ndescribe('[Integration] API \u002Fusers', () => {\n  beforeAll(async () => {\n    await setupTestDatabase();\n  });\n\n  afterAll(async () => {\n    await teardownTestDatabase();\n  });\n\n  it('should create user and return 201', async () => {\n    const response = await request(app)\n      .post('\u002Fusers')\n      .send({ name: 'Test', email: 'test@example.com' });\n\n    expect(response.status).toBe(201);\n    expect(response.body.id).toBeDefined();\n  });\n});\n```\n\n### E2E Test\n```javascript\ndescribe('[E2E] User Registration Flow', () => {\n  it('should complete registration successfully', async ({ page }) => {\n    await page.goto('\u002Fregister');\n\n    await page.fill('[data-testid=\"email\"]', 'new@example.com');\n    await page.fill('[data-testid=\"password\"]', 'SecurePass123!');\n    await page.click('[data-testid=\"submit\"]');\n\n    await expect(page.locator('.welcome-message')).toBeVisible();\n    await expect(page).toHaveURL('\u002Fdashboard');\n  });\n});\n```\n\n## Coverage Strategy\n\n### What to Cover\n- ✅ Business logic (100%)\n- ✅ Edge cases and error handling (90%+)\n- ✅ API contracts (100%)\n- ✅ Critical user paths (E2E)\n- ⚠️ UI components (snapshot + interaction)\n- ❌ Third-party library internals\n- ❌ Simple getters\u002Fsetters\n\n### Coverage Thresholds\n```json\n{\n  \"coverageThreshold\": {\n    \"global\": {\n      \"branches\": 80,\n      \"functions\": 80,\n      \"lines\": 80,\n      \"statements\": 80\n    },\n    \"src\u002Fcore\u002F\": {\n      \"branches\": 95,\n      \"functions\": 95\n    }\n  }\n}\n```\n\n## Test Data Management\n\n### Factories\u002FBuilders\n```javascript\n\u002F\u002F factories\u002Fuser.js\nexport const userFactory = (overrides = {}) => ({\n  id: faker.string.uuid(),\n  name: faker.person.fullName(),\n  email: faker.internet.email(),\n  createdAt: new Date(),\n  ...overrides,\n});\n\n\u002F\u002F Usage\nconst admin = userFactory({ role: 'admin' });\n```\n\n### Fixtures\n```javascript\n\u002F\u002F fixtures\u002Fusers.json\n{\n  \"validUser\": { \"name\": \"Test\", \"email\": \"test@example.com\" },\n  \"invalidUser\": { \"name\": \"\", \"email\": \"invalid\" }\n}\n```\n\n## Mocking Strategy\n\n### When to Mock\n- ✅ External APIs and services\n- ✅ Database in unit tests\n- ✅ Time\u002FDate for determinism\n- ✅ Random values\n- ❌ Internal modules (usually)\n- ❌ The code under test\n\n### Mock Examples\n```javascript\n\u002F\u002F API mocking with MSW\nimport { http, HttpResponse } from 'msw';\n\nexport const handlers = [\n  http.get('\u002Fapi\u002Fusers', () => {\n    return HttpResponse.json([\n      { id: 1, name: 'John' },\n    ]);\n  }),\n];\n\n\u002F\u002F Time mocking\nvi.useFakeTimers();\nvi.setSystemTime(new Date('2024-01-01'));\n```\n\n## Test Validation Loop\n\nAfter writing tests, run this validation:\n\n```\nTest Validation:\n- [ ] All tests pass: `npm test`\n- [ ] Coverage meets thresholds: `npm test -- --coverage`\n- [ ] No flaky tests (run multiple times)\n- [ ] Tests are independent (order doesn't matter)\n- [ ] Test names clearly describe behavior\n```\n\nIf any tests fail, fix them before proceeding. If coverage is below target, add more tests for uncovered code paths.\n\n```bash\n# Run tests\nnpm test\n\n# Run with coverage\nnpm test -- --coverage\n\n# Run specific test file\nnpm test -- path\u002Fto\u002Ftest.spec.ts\n\n# Run in watch mode during development\nnpm test -- --watch\n```\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fcloudai-x\u002Fdesigning-tests",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":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill designing-tests",{"tool":62,"command":63},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill designing-tests",{"tool":65,"command":66},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill designing-tests","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcloudai-x\u002Fdesigning-tests\u002FSKILL.md",true,[70,76,82,86,90],{"path":71,"resourceType":72,"resourceTypeDesc":73,"sizeBytes":74,"sourceHtmlUrl":75},".DS_Store","OTHER","其他",6148,"https:\u002F\u002Fgithub.com\u002Fmantrandev\u002Fmydotbot\u002Fblob\u002Fmain\u002Fai\u002Fweb\u002Fagent-browser\u002F.DS_Store",{"path":77,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002F.gitkeep","REFERENCE","参考文档",0,"https:\u002F\u002Fgithub.com\u002Fmantrandev\u002Fmydotbot\u002Fblob\u002Fmain\u002Fai\u002Fweb\u002Fagent-browser\u002Freferences\u002F.gitkeep",{"path":83,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":84,"sourceHtmlUrl":85},"references\u002Fagent-browser-vs-chrome-devtools.md",3832,"https:\u002F\u002Fgithub.com\u002Fmantrandev\u002Fmydotbot\u002Fblob\u002Fmain\u002Fai\u002Fweb\u002Fagent-browser\u002Freferences\u002Fagent-browser-vs-chrome-devtools.md",{"path":87,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":88,"sourceHtmlUrl":89},"references\u002Fbrowserbase-cloud-setup.md",4000,"https:\u002F\u002Fgithub.com\u002Fmantrandev\u002Fmydotbot\u002Fblob\u002Fmain\u002Fai\u002Fweb\u002Fagent-browser\u002Freferences\u002Fbrowserbase-cloud-setup.md",{"path":91,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":92,"sourceHtmlUrl":93},"skill-report.json",12615,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcloudai-x\u002Fdesigning-tests\u002Fskill-report.json",[95,107,117,126,132,139],{"skillNo":96,"name":97,"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":98,"categories":99,"keywords":103,"publishedAt":42},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[100],{"categoryNo":101,"categoryName":102,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[104,105,106],"model","model hierarchy","model hierarchy skill",{"skillNo":108,"name":109,"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":110,"categories":111,"keywords":113,"publishedAt":42},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[112],{"categoryNo":101,"categoryName":102,"taxonomyType":21,"taxonomyTypeDesc":22},[114,115,116],"MCP","zoom","zoom mcp",{"skillNo":118,"name":119,"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":120,"categories":121,"keywords":122,"publishedAt":42},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[123,124,125,115],"sdk","zoom apps sdk","apps",{"skillNo":127,"name":128,"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":129,"categories":130,"keywords":131,"publishedAt":42},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[128],{"skillNo":133,"name":134,"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":135,"categories":136,"keywords":138,"publishedAt":42},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[137],{"categoryNo":101,"categoryName":102,"taxonomyType":21,"taxonomyTypeDesc":22},[134],{"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":144,"publishedAt":42},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[141]]