[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7BF6RNH0CB0JCDSWVRKB1CM":3,"skill-same:01M7BF6RNH0CB0JCDSWVRKB1CM":48},{"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":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":30,"ownerHtmlUrl":31,"ownerBlogUrl":6,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M7BF6RNH0CB0JCDSWVRKB1CM","tdd-workflow",null,"Yeni özellikler yazarken, hata düzeltirken veya kod refactor ederken bu skill'i kullanın. Unit, integration ve E2E testlerini içeren %80+ kapsam ile test güdümlü geliştirmeyi zorlar.","YYC-Cube\u002FYYC3-Knowledge-Base","YYC-Cube","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F235006543?v=4","01M79J2PH4SWD2X0825X6PN748","yyc3","01M79J2PHVK3F6ZBYT8K2SCZCW",1,"MIT","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-AI-应用工具\u002FYYC3-AI-应用工具-Everything-claude-code\u002Fdocs\u002Ftr\u002Fskills\u002Ftdd-workflow\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: tdd-workflow\ndescription: Yeni özellikler yazarken, hata düzeltirken veya kod refactor ederken bu skill'i kullanın. Unit, integration ve E2E testlerini içeren %80+ kapsam ile test güdümlü geliştirmeyi zorlar.\norigin: ECC\n---\n\n# Test Güdümlü Geliştirme İş Akışı\n\nBu skill tüm kod geliştirmenin kapsamlı test kapsamı ile TDD ilkelerini takip etmesini sağlar.\n\n## Ne Zaman Aktifleştirmelisiniz\n\n- Yeni özellikler veya fonksiyonellik yazarken\n- Hataları veya sorunları düzeltirken\n- Mevcut kodu refactor ederken\n- API endpoint'leri eklerken\n- Yeni bileşenler oluştururken\n\n## Temel İlkeler\n\n### 1. Koddan ÖNCE Testler\nHER ZAMAN önce testleri yazın, sonra testleri geçmesi için kod uygulayın.\n\n### 2. Kapsam Gereksinimleri\n- Minimum %80 kapsam (unit + integration + E2E)\n- Tüm uç durumlar kapsanmış\n- Hata senaryoları test edilmiş\n- Sınır koşulları doğrulanmış\n\n### 3. Test Tipleri\n\n#### Unit Testler\n- Bireysel fonksiyonlar ve yardımcı araçlar\n- Bileşen mantığı\n- Pure fonksiyonlar\n- Yardımcılar ve utilities\n\n#### Integration Testler\n- API endpoint'leri\n- Veritabanı operasyonları\n- Service etkileşimleri\n- Harici API çağrıları\n\n#### E2E Testler (Playwright)\n- Kritik kullanıcı akışları\n- Tam iş akışları\n- Tarayıcı otomasyonu\n- UI etkileşimleri\n\n## TDD İş Akışı Adımları\n\n### Adım 1: Kullanıcı Hikayeleri Yazın\n```\n[Rol] olarak, [eylem] yapmak istiyorum, böylece [fayda] elde ederim\n\nÖrnek:\nKullanıcı olarak, marketleri semantik olarak aramak istiyorum,\nböylece tam anahtar kelimeler olmasa bile ilgili marketleri bulabilirim.\n```\n\n### Adım 2: Test Senaryoları Oluşturun\nHer kullanıcı hikayesi için kapsamlı test senaryoları oluşturun:\n\n```typescript\ndescribe('Semantik Arama', () => {\n  it('sorgu için ilgili marketleri döndürür', async () => {\n    \u002F\u002F Test implementasyonu\n  })\n\n  it('boş sorguyu zarif şekilde işler', async () => {\n    \u002F\u002F Uç durumu test et\n  })\n\n  it('Redis kullanılamazsa substring aramaya geri döner', async () => {\n    \u002F\u002F Fallback davranışını test et\n  })\n\n  it('sonuçları benzerlik skoruna göre sıralar', async () => {\n    \u002F\u002F Sıralama mantığını test et\n  })\n})\n```\n\n### Adım 3: Testleri Çalıştırın (Başarısız Olmalı)\n```bash\nnpm test\n# Testler başarısız olmalı - henüz implement etmedik\n```\n\n### Adım 4: Kod Uygulayın\nTestleri geçmesi için minimal kod yazın:\n\n```typescript\n\u002F\u002F Testler tarafından yönlendirilen implementasyon\nexport async function searchMarkets(query: string) {\n  \u002F\u002F Implementasyon buraya\n}\n```\n\n### Adım 5: Testleri Tekrar Çalıştırın\n```bash\nnpm test\n# Testler artık geçmeli\n```\n\n### Adım 6: Refactor Edin\nTestleri yeşil tutarken kod kalitesini iyileştirin:\n- Tekrarı kaldırın\n- İsimlendirmeyi iyileştirin\n- Performansı optimize edin\n- Okunabilirliği artırın\n\n### Adım 7: Kapsamı Doğrulayın\n```bash\nnpm run test:coverage\n# %80+ kapsam sağlandığını doğrula\n```\n\n## Test Kalıpları\n\n### Unit Test Kalıbı (Jest\u002FVitest)\n```typescript\nimport { render, screen, fireEvent } from '@testing-library\u002Freact'\nimport { Button } from '.\u002FButton'\n\ndescribe('Button Bileşeni', () => {\n  it('doğru metinle render eder', () => {\n    render(\u003CButton>Tıkla\u003C\u002FButton>)\n    expect(screen.getByText('Tıkla')).toBeInTheDocument()\n  })\n\n  it('tıklandığında onClick\\'i çağırır', () => {\n    const handleClick = jest.fn()\n    render(\u003CButton onClick={handleClick}>Tıkla\u003C\u002FButton>)\n\n    fireEvent.click(screen.getByRole('button'))\n\n    expect(handleClick).toHaveBeenCalledTimes(1)\n  })\n\n  it('disabled prop true olduğunda devre dışı kalır', () => {\n    render(\u003CButton disabled>Tıkla\u003C\u002FButton>)\n    expect(screen.getByRole('button')).toBeDisabled()\n  })\n})\n```\n\n### API Integration Test Kalıbı\n```typescript\nimport { NextRequest } from 'next\u002Fserver'\nimport { GET } from '.\u002Froute'\n\ndescribe('GET \u002Fapi\u002Fmarkets', () => {\n  it('marketleri başarıyla döndürür', async () => {\n    const request = new NextRequest('http:\u002F\u002Flocalhost\u002Fapi\u002Fmarkets')\n    const response = await GET(request)\n    const data = await response.json()\n\n    expect(response.status).toBe(200)\n    expect(data.success).toBe(true)\n    expect(Array.isArray(data.data)).toBe(true)\n  })\n\n  it('query parametrelerini validate eder', async () => {\n    const request = new NextRequest('http:\u002F\u002Flocalhost\u002Fapi\u002Fmarkets?limit=invalid')\n    const response = await GET(request)\n\n    expect(response.status).toBe(400)\n  })\n\n  it('veritabanı hatalarını zarif şekilde işler', async () => {\n    \u002F\u002F Veritabanı başarısızlığını mock'la\n    const request = new NextRequest('http:\u002F\u002Flocalhost\u002Fapi\u002Fmarkets')\n    \u002F\u002F Hata işlemeyi test et\n  })\n})\n```\n\n### E2E Test Kalıbı (Playwright)\n```typescript\nimport { test, expect } from '@playwright\u002Ftest'\n\ntest('kullanıcı marketleri arayabilir ve filtreleyebilir', async ({ page }) => {\n  \u002F\u002F Markets sayfasına git\n  await page.goto('\u002F')\n  await page.click('a[href=\"\u002Fmarkets\"]')\n\n  \u002F\u002F Sayfanın yüklendiğini doğrula\n  await expect(page.locator('h1')).toContainText('Markets')\n\n  \u002F\u002F Marketleri ara\n  await page.fill('input[placeholder=\"Marketleri ara\"]', 'election')\n\n  \u002F\u002F Debounce ve sonuçları bekle\n  await page.waitForTimeout(600)\n\n  \u002F\u002F Arama sonuçlarının gösterildiğini doğrula\n  const results = page.locator('[data-testid=\"market-card\"]')\n  await expect(results).toHaveCount(5, { timeout: 5000 })\n\n  \u002F\u002F Sonuçların arama terimini içerdiğini doğrula\n  const firstResult = results.first()\n  await expect(firstResult).toContainText('election', { ignoreCase: true })\n\n  \u002F\u002F Duruma göre filtrele\n  await page.click('button:has-text(\"Aktif\")')\n\n  \u002F\u002F Filtrelenmiş sonuçları doğrula\n  await expect(results).toHaveCount(3)\n})\n\ntest('kullanıcı yeni market oluşturabilir', async ({ page }) => {\n  \u002F\u002F Önce login ol\n  await page.goto('\u002Fcreator-dashboard')\n\n  \u002F\u002F Market oluşturma formunu doldur\n  await page.fill('input[name=\"name\"]', 'Test Market')\n  await page.fill('textarea[name=\"description\"]', 'Test açıklama')\n  await page.fill('input[name=\"endDate\"]', '2025-12-31')\n\n  \u002F\u002F Formu gönder\n  await page.click('button[type=\"submit\"]')\n\n  \u002F\u002F Başarı mesajını doğrula\n  await expect(page.locator('text=Market başarıyla oluşturuldu')).toBeVisible()\n\n  \u002F\u002F Market sayfasına yönlendirmeyi doğrula\n  await expect(page).toHaveURL(\u002F\\\u002Fmarkets\\\u002Ftest-market\u002F)\n})\n```\n\n## Test Dosya Organizasyonu\n\n```\nsrc\u002F\n├── components\u002F\n│   ├── Button\u002F\n│   │   ├── Button.tsx\n│   │   ├── Button.test.tsx          # Unit testler\n│   │   └── Button.stories.tsx       # Storybook\n│   └── MarketCard\u002F\n│       ├── MarketCard.tsx\n│       └── MarketCard.test.tsx\n├── app\u002F\n│   └── api\u002F\n│       └── markets\u002F\n│           ├── route.ts\n│           └── route.test.ts         # Integration testler\n└── e2e\u002F\n    ├── markets.spec.ts               # E2E testler\n    ├── trading.spec.ts\n    └── auth.spec.ts\n```\n\n## Harici Servisleri Mock'lama\n\n### Supabase Mock\n```typescript\njest.mock('@\u002Flib\u002Fsupabase', () => ({\n  supabase: {\n    from: jest.fn(() => ({\n      select: jest.fn(() => ({\n        eq: jest.fn(() => Promise.resolve({\n          data: [{ id: 1, name: 'Test Market' }],\n          error: null\n        }))\n      }))\n    }))\n  }\n}))\n```\n\n### Redis Mock\n```typescript\njest.mock('@\u002Flib\u002Fredis', () => ({\n  searchMarketsByVector: jest.fn(() => Promise.resolve([\n    { slug: 'test-market', similarity_score: 0.95 }\n  ])),\n  checkRedisHealth: jest.fn(() => Promise.resolve({ connected: true }))\n}))\n```\n\n### OpenAI Mock\n```typescript\njest.mock('@\u002Flib\u002Fopenai', () => ({\n  generateEmbedding: jest.fn(() => Promise.resolve(\n    new Array(1536).fill(0.1) \u002F\u002F Mock 1536-boyutlu embedding\n  ))\n}))\n```\n\n## Test Kapsamı Doğrulama\n\n### Kapsam Raporu Çalıştır\n```bash\nnpm run test:coverage\n```\n\n### Kapsam Eşikleri\n```json\n{\n  \"jest\": {\n    \"coverageThresholds\": {\n      \"global\": {\n        \"branches\": 80,\n        \"functions\": 80,\n        \"lines\": 80,\n        \"statements\": 80\n      }\n    }\n  }\n}\n```\n\n## Kaçınılması Gereken Yaygın Test Hataları\n\n### FAIL: YANLIŞ: Implementasyon Detaylarını Test Etme\n```typescript\n\u002F\u002F İç state'i test etme\nexpect(component.state.count).toBe(5)\n```\n\n### PASS: DOĞRU: Kullanıcı Tarafından Görünen Davranışı Test Et\n```typescript\n\u002F\u002F Kullanıcıların gördüğünü test et\nexpect(screen.getByText('Sayı: 5')).toBeInTheDocument()\n```\n\n### FAIL: YANLIŞ: Kırılgan Selector'lar\n```typescript\n\u002F\u002F Kolayca bozulur\nawait page.click('.css-class-xyz')\n```\n\n### PASS: DOĞRU: Semantik Selector'lar\n```typescript\n\u002F\u002F Değişikliklere karşı dayanıklı\nawait page.click('button:has-text(\"Gönder\")')\nawait page.click('[data-testid=\"submit-button\"]')\n```\n\n### FAIL: YANLIŞ: Test İzolasyonu Yok\n```typescript\n\u002F\u002F Testler birbirine bağımlı\ntest('kullanıcı oluşturur', () => { \u002F* ... *\u002F })\ntest('aynı kullanıcıyı günceller', () => { \u002F* önceki teste bağımlı *\u002F })\n```\n\n### PASS: DOĞRU: Bağımsız Testler\n```typescript\n\u002F\u002F Her test kendi verisini hazırlar\ntest('kullanıcı oluşturur', () => {\n  const user = createTestUser()\n  \u002F\u002F Test mantığı\n})\n\ntest('kullanıcı günceller', () => {\n  const user = createTestUser()\n  \u002F\u002F Güncelleme mantığı\n})\n```\n\n## Sürekli Test\n\n### Geliştirme Sırasında Watch Modu\n```bash\nnpm test -- --watch\n# Dosya değişikliklerinde testler otomatik çalışır\n```\n\n### Pre-Commit Hook\n```bash\n# Her commit öncesi çalışır\nnpm test && npm run lint\n```\n\n### CI\u002FCD Entegrasyonu\n```yaml\n# GitHub Actions\n- name: Run Tests\n  run: npm test -- --coverage\n- name: Upload Coverage\n  uses: codecov\u002Fcodecov-action@v3\n```\n\n## En İyi Uygulamalar\n\n1. **Önce Testleri Yaz** - Her zaman TDD\n2. **Test Başına Bir Assert** - Tek davranışa odaklan\n3. **Açıklayıcı Test İsimleri** - Neyin test edildiğini açıkla\n4. **Arrange-Act-Assert** - Net test yapısı\n5. **Harici Bağımlılıkları Mock'la** - Unit testleri izole et\n6. **Uç Durumları Test Et** - Null, undefined, boş, büyük\n7. **Hata Yollarını Test Et** - Sadece happy path değil\n8. **Testleri Hızlı Tut** - Unit testler \u003C 50ms her biri\n9. **Testlerden Sonra Temizle** - Yan etki yok\n10. **Kapsam Raporlarını İncele** - Boşlukları tespit et\n\n## Başarı Metrikleri\n\n- %80+ kod kapsamı sağlanmış\n- Tüm testler geçiyor (yeşil)\n- Atlanmış veya devre dışı test yok\n- Hızlı test yürütme (\u003C 30s unit testler için)\n- E2E testler kritik kullanıcı akışlarını kapsıyor\n- Testler production'dan önce hataları yakalar\n\n---\n\n**Unutmayın**: Testler opsiyonel değildir. Güvenli refactoring, hızlı geliştirme ve production güvenilirliği sağlayan güvenlik ağıdırlar.\n","# Test Güdümlü Geliştirme İş Akışı\n\nBu skill tüm kod geliştirmenin kapsamlı test kapsamı ile TDD ilkelerini takip etmesini sağlar.\n\n## Ne Zaman Aktifleştirmelisiniz\n\n- Yeni özellikler veya fonksiyonellik yazarken\n- Hataları veya sorunları düzeltirken\n- Mevcut kodu refactor ederken\n- API endpoint'leri eklerken\n- Yeni bileşenler oluştururken\n\n## Temel İlkeler\n\n### 1. Koddan ÖNCE Testler\nHER ZAMAN önce testleri yazın, sonra testleri geçmesi için kod uygulayın.\n\n### 2. Kapsam Gereksinimleri\n- Minimum %80 kapsam (unit + integration + E2E)\n- Tüm uç durumlar kapsanmış\n- Hata senaryoları test edilmiş\n- Sınır koşulları doğrulanmış\n\n### 3. Test Tipleri\n\n#### Unit Testler\n- Bireysel fonksiyonlar ve yardımcı araçlar\n- Bileşen mantığı\n- Pure fonksiyonlar\n- Yardımcılar ve utilities\n\n#### Integration Testler\n- API endpoint'leri\n- Veritabanı operasyonları\n- Service etkileşimleri\n- Harici API çağrıları\n\n#### E2E Testler (Playwright)\n- Kritik kullanıcı akışları\n- Tam iş akışları\n- Tarayıcı otomasyonu\n- UI etkileşimleri\n\n## TDD İş Akışı Adımları\n\n### Adım 1: Kullanıcı Hikayeleri Yazın\n```\n[Rol] olarak, [eylem] yapmak istiyorum, böylece [fayda] elde ederim\n\nÖrnek:\nKullanıcı olarak, marketleri semantik olarak aramak istiyorum,\nböylece tam anahtar kelimeler olmasa bile ilgili marketleri bulabilirim.\n```\n\n### Adım 2: Test Senaryoları Oluşturun\nHer kullanıcı hikayesi için kapsamlı test senaryoları oluşturun:\n\n```typescript\ndescribe('Semantik Arama', () => {\n  it('sorgu için ilgili marketleri döndürür', async () => {\n    \u002F\u002F Test implementasyonu\n  })\n\n  it('boş sorguyu zarif şekilde işler', async () => {\n    \u002F\u002F Uç durumu test et\n  })\n\n  it('Redis kullanılamazsa substring aramaya geri döner', async () => {\n    \u002F\u002F Fallback davranışını test et\n  })\n\n  it('sonuçları benzerlik skoruna göre sıralar', async () => {\n    \u002F\u002F Sıralama mantığını test et\n  })\n})\n```\n\n### Adım 3: Testleri Çalıştırın (Başarısız Olmalı)\n```bash\nnpm test\n# Testler başarısız olmalı - henüz implement etmedik\n```\n\n### Adım 4: Kod Uygulayın\nTestleri geçmesi için minimal kod yazın:\n\n```typescript\n\u002F\u002F Testler tarafından yönlendirilen implementasyon\nexport async function searchMarkets(query: string) {\n  \u002F\u002F Implementasyon buraya\n}\n```\n\n### Adım 5: Testleri Tekrar Çalıştırın\n```bash\nnpm test\n# Testler artık geçmeli\n```\n\n### Adım 6: Refactor Edin\nTestleri yeşil tutarken kod kalitesini iyileştirin:\n- Tekrarı kaldırın\n- İsimlendirmeyi iyileştirin\n- Performansı optimize edin\n- Okunabilirliği artırın\n\n### Adım 7: Kapsamı Doğrulayın\n```bash\nnpm run test:coverage\n# %80+ kapsam sağlandığını doğrula\n```\n\n## Test Kalıpları\n\n### Unit Test Kalıbı (Jest\u002FVitest)\n```typescript\nimport { render, screen, fireEvent } from '@testing-library\u002Freact'\nimport { Button } from '.\u002FButton'\n\ndescribe('Button Bileşeni', () => {\n  it('doğru metinle render eder', () => {\n    render(\u003CButton>Tıkla\u003C\u002FButton>)\n    expect(screen.getByText('Tıkla')).toBeInTheDocument()\n  })\n\n  it('tıklandığında onClick\\'i çağırır', () => {\n    const handleClick = jest.fn()\n    render(\u003CButton onClick={handleClick}>Tıkla\u003C\u002FButton>)\n\n    fireEvent.click(screen.getByRole('button'))\n\n    expect(handleClick).toHaveBeenCalledTimes(1)\n  })\n\n  it('disabled prop true olduğunda devre dışı kalır', () => {\n    render(\u003CButton disabled>Tıkla\u003C\u002FButton>)\n    expect(screen.getByRole('button')).toBeDisabled()\n  })\n})\n```\n\n### API Integration Test Kalıbı\n```typescript\nimport { NextRequest } from 'next\u002Fserver'\nimport { GET } from '.\u002Froute'\n\ndescribe('GET \u002Fapi\u002Fmarkets', () => {\n  it('marketleri başarıyla döndürür', async () => {\n    const request = new NextRequest('http:\u002F\u002Flocalhost\u002Fapi\u002Fmarkets')\n    const response = await GET(request)\n    const data = await response.json()\n\n    expect(response.status).toBe(200)\n    expect(data.success).toBe(true)\n    expect(Array.isArray(data.data)).toBe(true)\n  })\n\n  it('query parametrelerini validate eder', async () => {\n    const request = new NextRequest('http:\u002F\u002Flocalhost\u002Fapi\u002Fmarkets?limit=invalid')\n    const response = await GET(request)\n\n    expect(response.status).toBe(400)\n  })\n\n  it('veritabanı hatalarını zarif şekilde işler', async () => {\n    \u002F\u002F Veritabanı başarısızlığını mock'la\n    const request = new NextRequest('http:\u002F\u002Flocalhost\u002Fapi\u002Fmarkets')\n    \u002F\u002F Hata işlemeyi test et\n  })\n})\n```\n\n### E2E Test Kalıbı (Playwright)\n```typescript\nimport { test, expect } from '@playwright\u002Ftest'\n\ntest('kullanıcı marketleri arayabilir ve filtreleyebilir', async ({ page }) => {\n  \u002F\u002F Markets sayfasına git\n  await page.goto('\u002F')\n  await page.click('a[href=\"\u002Fmarkets\"]')\n\n  \u002F\u002F Sayfanın yüklendiğini doğrula\n  await expect(page.locator('h1')).toContainText('Markets')\n\n  \u002F\u002F Marketleri ara\n  await page.fill('input[placeholder=\"Marketleri ara\"]', 'election')\n\n  \u002F\u002F Debounce ve sonuçları bekle\n  await page.waitForTimeout(600)\n\n  \u002F\u002F Arama sonuçlarının gösterildiğini doğrula\n  const results = page.locator('[data-testid=\"market-card\"]')\n  await expect(results).toHaveCount(5, { timeout: 5000 })\n\n  \u002F\u002F Sonuçların arama terimini içerdiğini doğrula\n  const firstResult = results.first()\n  await expect(firstResult).toContainText('election', { ignoreCase: true })\n\n  \u002F\u002F Duruma göre filtrele\n  await page.click('button:has-text(\"Aktif\")')\n\n  \u002F\u002F Filtrelenmiş sonuçları doğrula\n  await expect(results).toHaveCount(3)\n})\n\ntest('kullanıcı yeni market oluşturabilir', async ({ page }) => {\n  \u002F\u002F Önce login ol\n  await page.goto('\u002Fcreator-dashboard')\n\n  \u002F\u002F Market oluşturma formunu doldur\n  await page.fill('input[name=\"name\"]', 'Test Market')\n  await page.fill('textarea[name=\"description\"]', 'Test açıklama')\n  await page.fill('input[name=\"endDate\"]', '2025-12-31')\n\n  \u002F\u002F Formu gönder\n  await page.click('button[type=\"submit\"]')\n\n  \u002F\u002F Başarı mesajını doğrula\n  await expect(page.locator('text=Market başarıyla oluşturuldu')).toBeVisible()\n\n  \u002F\u002F Market sayfasına yönlendirmeyi doğrula\n  await expect(page).toHaveURL(\u002F\\\u002Fmarkets\\\u002Ftest-market\u002F)\n})\n```\n\n## Test Dosya Organizasyonu\n\n```\nsrc\u002F\n├── components\u002F\n│   ├── Button\u002F\n│   │   ├── Button.tsx\n│   │   ├── Button.test.tsx          # Unit testler\n│   │   └── Button.stories.tsx       # Storybook\n│   └── MarketCard\u002F\n│       ├── MarketCard.tsx\n│       └── MarketCard.test.tsx\n├── app\u002F\n│   └── api\u002F\n│       └── markets\u002F\n│           ├── route.ts\n│           └── route.test.ts         # Integration testler\n└── e2e\u002F\n    ├── markets.spec.ts               # E2E testler\n    ├── trading.spec.ts\n    └── auth.spec.ts\n```\n\n## Harici Servisleri Mock'lama\n\n### Supabase Mock\n```typescript\njest.mock('@\u002Flib\u002Fsupabase', () => ({\n  supabase: {\n    from: jest.fn(() => ({\n      select: jest.fn(() => ({\n        eq: jest.fn(() => Promise.resolve({\n          data: [{ id: 1, name: 'Test Market' }],\n          error: null\n        }))\n      }))\n    }))\n  }\n}))\n```\n\n### Redis Mock\n```typescript\njest.mock('@\u002Flib\u002Fredis', () => ({\n  searchMarketsByVector: jest.fn(() => Promise.resolve([\n    { slug: 'test-market', similarity_score: 0.95 }\n  ])),\n  checkRedisHealth: jest.fn(() => Promise.resolve({ connected: true }))\n}))\n```\n\n### OpenAI Mock\n```typescript\njest.mock('@\u002Flib\u002Fopenai', () => ({\n  generateEmbedding: jest.fn(() => Promise.resolve(\n    new Array(1536).fill(0.1) \u002F\u002F Mock 1536-boyutlu embedding\n  ))\n}))\n```\n\n## Test Kapsamı Doğrulama\n\n### Kapsam Raporu Çalıştır\n```bash\nnpm run test:coverage\n```\n\n### Kapsam Eşikleri\n```json\n{\n  \"jest\": {\n    \"coverageThresholds\": {\n      \"global\": {\n        \"branches\": 80,\n        \"functions\": 80,\n        \"lines\": 80,\n        \"statements\": 80\n      }\n    }\n  }\n}\n```\n\n## Kaçınılması Gereken Yaygın Test Hataları\n\n### FAIL: YANLIŞ: Implementasyon Detaylarını Test Etme\n```typescript\n\u002F\u002F İç state'i test etme\nexpect(component.state.count).toBe(5)\n```\n\n### PASS: DOĞRU: Kullanıcı Tarafından Görünen Davranışı Test Et\n```typescript\n\u002F\u002F Kullanıcıların gördüğünü test et\nexpect(screen.getByText('Sayı: 5')).toBeInTheDocument()\n```\n\n### FAIL: YANLIŞ: Kırılgan Selector'lar\n```typescript\n\u002F\u002F Kolayca bozulur\nawait page.click('.css-class-xyz')\n```\n\n### PASS: DOĞRU: Semantik Selector'lar\n```typescript\n\u002F\u002F Değişikliklere karşı dayanıklı\nawait page.click('button:has-text(\"Gönder\")')\nawait page.click('[data-testid=\"submit-button\"]')\n```\n\n### FAIL: YANLIŞ: Test İzolasyonu Yok\n```typescript\n\u002F\u002F Testler birbirine bağımlı\ntest('kullanıcı oluşturur', () => { \u002F* ... *\u002F })\ntest('aynı kullanıcıyı günceller', () => { \u002F* önceki teste bağımlı *\u002F })\n```\n\n### PASS: DOĞRU: Bağımsız Testler\n```typescript\n\u002F\u002F Her test kendi verisini hazırlar\ntest('kullanıcı oluşturur', () => {\n  const user = createTestUser()\n  \u002F\u002F Test mantığı\n})\n\ntest('kullanıcı günceller', () => {\n  const user = createTestUser()\n  \u002F\u002F Güncelleme mantığı\n})\n```\n\n## Sürekli Test\n\n### Geliştirme Sırasında Watch Modu\n```bash\nnpm test -- --watch\n# Dosya değişikliklerinde testler otomatik çalışır\n```\n\n### Pre-Commit Hook\n```bash\n# Her commit öncesi çalışır\nnpm test && npm run lint\n```\n\n### CI\u002FCD Entegrasyonu\n```yaml\n# GitHub Actions\n- name: Run Tests\n  run: npm test -- --coverage\n- name: Upload Coverage\n  uses: codecov\u002Fcodecov-action@v3\n```\n\n## En İyi Uygulamalar\n\n1. **Önce Testleri Yaz** - Her zaman TDD\n2. **Test Başına Bir Assert** - Tek davranışa odaklan\n3. **Açıklayıcı Test İsimleri** - Neyin test edildiğini açıkla\n4. **Arrange-Act-Assert** - Net test yapısı\n5. **Harici Bağımlılıkları Mock'la** - Unit testleri izole et\n6. **Uç Durumları Test Et** - Null, undefined, boş, büyük\n7. **Hata Yollarını Test Et** - Sadece happy path değil\n8. **Testleri Hızlı Tut** - Unit testler \u003C 50ms her biri\n9. **Testlerden Sonra Temizle** - Yan etki yok\n10. **Kapsam Raporlarını İncele** - Boşlukları tespit et\n\n## Başarı Metrikleri\n\n- %80+ kod kapsamı sağlanmış\n- Tüm testler geçiyor (yeşil)\n- Atlanmış veya devre dışı test yok\n- Hızlı test yürütme (\u003C 30s unit testler için)\n- E2E testler kritik kullanıcı akışlarını kapsıyor\n- Testler production'dan önce hataları yakalar\n\n---\n\n**Unutmayın**: Testler opsiyonel değildir. Güvenli refactoring, hızlı geliştirme ve production güvenilirliği sağlayan güvenlik ağıdırlar.\n",{"name":5,"origin":24,"description":7},"ECC","main","87afe6ce96220accf50a345dea46784c8c9f210e","YYC3-AI-应用工具\u002FYYC3-AI-应用工具-Everything-claude-code\u002Fdocs\u002Ftr\u002Fskills\u002Ftdd-workflow",0,"https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base","https:\u002F\u002Fkb.yyc3.top\u002F","https:\u002F\u002Fgithub.com\u002FYYC-Cube","万象归元于云枢 | 深栈智启新纪元","2026-11-10 10:37:32",{"source":8,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add YYC-Cube\u002FYYC3-Knowledge-Base --skill tdd-workflow",{"tool":40,"command":41},"bunx","bunx skills add YYC-Cube\u002FYYC3-Knowledge-Base --skill tdd-workflow",{"tool":43,"command":44},"pnpm","pnpm dlx skills add YYC-Cube\u002FYYC3-Knowledge-Base --skill tdd-workflow","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-AI-应用工具\u002FYYC3-AI-应用工具-Everything-claude-code\u002Fdocs\u002Ftr\u002Fskills\u002Ftdd-workflow\u002FSKILL.md",true,[],[49,56,63,70,77,84],{"skillNo":50,"name":51,"nameZh":6,"description":52,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":53,"categories":54,"keywords":55,"publishedAt":19},"01M7CTDWHERCXPQCP0K03A86AS","vercel-sandbox","Run agent-browser + Chrome inside Vercel Sandbox microVMs for browser automation from any Vercel-deployed app. Use when the user needs browser automation in a Vercel app (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.), wants to run headless Chrome without binary size limits, needs persistent browser sessions across commands, or wants ephemeral isolated browser environments. Triggers include \"Vercel Sandbox browser\", \"microVM Chrome\", \"agent-browser in sandbox\", \"browser automation on Vercel\", or any task requiring Chrome in a Vercel Sandbox.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fvercel-sandbox\u002FSKILL.md",[],[],{"skillNo":57,"name":58,"nameZh":6,"description":59,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":60,"categories":61,"keywords":62,"publishedAt":19},"01M7CTD8D2BNJY54S65M47HEJA","slack","Interact with Slack workspaces using browser automation. Use when the user needs to check unread channels, navigate Slack, send messages, extract data, find information, search conversations, or automate any Slack task. Triggers include \"check my Slack\", \"what channels have unreads\", \"send a message to\", \"search Slack for\", \"extract from Slack\", \"find who said\", or any task requiring programmatic Slack interaction.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fslack\u002FSKILL.md",[],[],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":19},"01M7CTCSSB8ZP3Q58C3YZDZK1W","electron","Automate Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify, etc.) using agent-browser via Chrome DevTools Protocol. Use when the user needs to interact with an Electron app, automate a desktop app, connect to a running app, control a native app, or test an Electron application. Triggers include \"automate Slack app\", \"control VS Code\", \"interact with Discord app\", \"test this Electron app\", \"connect to desktop app\", or any task requiring automation of a native Electron application.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Felectron\u002FSKILL.md",[],[],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":19},"01M7CTCBJY76688V4DCZGWFHGQ","dogfood","Systematically explore and test a web application to find bugs, UX issues, and other problems. Use when asked to \"dogfood\", \"QA\", \"exploratory test\", \"find issues\", \"bug hunt\", \"test this app\u002Fsite\u002Fplatform\", or review the quality of a web application. Produces a structured report with full reproduction evidence -- step-by-step screenshots, repro videos, and detailed repro steps for every issue -- so findings can be handed directly to the responsible teams.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fdogfood\u002FSKILL.md",[],[],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":19},"01M7CTC4H0FFGVEAQR9PA4GA1A","agent-browser","Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to \"open a website\", \"fill out a form\", \"click a button\", \"take a screenshot\", \"scrape data from a page\", \"test this web app\", \"login to a site\", \"automate browser actions\", or any task requiring programmatic web interaction.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fagent-browser\u002FSKILL.md",[],[],{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":90,"publishedAt":19},"01M7CTBKVFYBG78FDSABSDJTTQ","shadcn","Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI, including chat interfaces. Provides project context, component docs, and usage examples. Applies when working with shadcn\u002Fui, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for \"shadcn init\", \"create an app with --preset\", \"switch to --preset\", and for building a design system or applying a DESIGN.md or brand spec to shadcn\u002Fui.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-UI-界面组件\u002FYYC3-UI-界面组件-ui\u002Fskills\u002Fshadcn\u002FSKILL.md",[],[]]