<< All versions
Skill v1.0.1
currentAutomated scan100/100wolverin0/claude-skills/tdd-workflow
1 files
──Details
PublishedMay 24, 2026 at 06:48 PM
Content Hashsha256:dbf3aeca1b90f56e...
Git SHA0d301f7bf6a8
Bump Typepatch
──Files
Files (1 file, 9.4 KB)
SKILL.md9.4 KBactive
SKILL.md · 411 lines · 9.4 KB
version: "1.0.1" name: tdd-workflow description: Use this skill when writing new features, fixing bugs, or refactoring code. Enforces test-driven development with 80%+ coverage including unit, integration, and E2E tests.
Test-Driven Development Workflow
This skill ensures all code development follows TDD principles with comprehensive test coverage.
When to Activate
- Writing new features or functionality
- Fixing bugs or issues
- Refactoring existing code
- Adding API endpoints
- Creating new components
Core Principles
1. Tests BEFORE Code
ALWAYS write tests first, then implement code to make tests pass.
2. Coverage Requirements
- Minimum 80% coverage (unit + integration + E2E)
- All edge cases covered
- Error scenarios tested
- Boundary conditions verified
3. Test Types
Unit Tests
- Individual functions and utilities
- Component logic
- Pure functions
- Helpers and utilities
Integration Tests
- API endpoints
- Database operations
- Service interactions
- External API calls
E2E Tests (Playwright)
- Critical user flows
- Complete workflows
- Browser automation
- UI interactions
TDD Workflow Steps
Step 1: Write User Journeys
As a [role], I want to [action], so that [benefit]Example:As a user, I want to search for markets semantically,so that I can find relevant markets even without exact keywords.
Step 2: Generate Test Cases
For each user journey, create comprehensive test cases:
typescript
describe('Semantic Search', () => {it('returns relevant markets for query', async () => {// Test implementation})it('handles empty query gracefully', async () => {// Test edge case})it('falls back to substring search when Redis unavailable', async () => {// Test fallback behavior})it('sorts results by similarity score', async () => {// Test sorting logic})})
Step 3: Run Tests (They Should Fail)
bash
npm test# Tests should fail - we haven't implemented yet
Step 4: Implement Code
Write minimal code to make tests pass:
typescript
// Implementation guided by testsexport async function searchMarkets(query: string) {// Implementation here}
Step 5: Run Tests Again
bash
npm test# Tests should now pass
Step 6: Refactor
Improve code quality while keeping tests green:
- Remove duplication
- Improve naming
- Optimize performance
- Enhance readability
Step 7: Verify Coverage
bash
npm run test:coverage# Verify 80%+ coverage achieved
Testing Patterns
Unit Test Pattern (Jest/Vitest)
typescript
import { render, screen, fireEvent } from '@testing-library/react'import { Button } from './Button'describe('Button Component', () => {it('renders with correct text', () => {render(<Button>Click me</Button>)expect(screen.getByText('Click me')).toBeInTheDocument()})it('calls onClick when clicked', () => {const handleClick = jest.fn()render(<Button onClick={handleClick}>Click</Button>)fireEvent.click(screen.getByRole('button'))expect(handleClick).toHaveBeenCalledTimes(1)})it('is disabled when disabled prop is true', () => {render(<Button disabled>Click</Button>)expect(screen.getByRole('button')).toBeDisabled()})})
API Integration Test Pattern
typescript
import { NextRequest } from 'next/server'import { GET } from './route'describe('GET /api/markets', () => {it('returns markets successfully', async () => {const request = new NextRequest('http://localhost/api/markets')const response = await GET(request)const data = await response.json()expect(response.status).toBe(200)expect(data.success).toBe(true)expect(Array.isArray(data.data)).toBe(true)})it('validates query parameters', async () => {const request = new NextRequest('http://localhost/api/markets-limit=invalid')const response = await GET(request)expect(response.status).toBe(400)})it('handles database errors gracefully', async () => {// Mock database failureconst request = new NextRequest('http://localhost/api/markets')// Test error handling})})
E2E Test Pattern (Playwright)
typescript
import { test, expect } from '@playwright/test'test('user can search and filter markets', async ({ page }) => {// Navigate to markets pageawait page.goto('/')await page.click('a[href="/markets"]')// Verify page loadedawait expect(page.locator('h1')).toContainText('Markets')// Search for marketsawait page.fill('input[placeholder="Search markets"]', 'election')// Wait for debounce and resultsawait page.waitForTimeout(600)// Verify search results displayedconst results = page.locator('[data-testid="market-card"]')await expect(results).toHaveCount(5, { timeout: 5000 })// Verify results contain search termconst firstResult = results.first()await expect(firstResult).toContainText('election', { ignoreCase: true })// Filter by statusawait page.click('button:has-text("Active")')// Verify filtered resultsawait expect(results).toHaveCount(3)})test('user can create a new market', async ({ page }) => {// Login firstawait page.goto('/creator-dashboard')// Fill market creation formawait page.fill('input[name="name"]', 'Test Market')await page.fill('textarea[name="description"]', 'Test description')await page.fill('input[name="endDate"]', '2025-12-31')// Submit formawait page.click('button[type="submit"]')// Verify success messageawait expect(page.locator('text=Market created successfully')).toBeVisible()// Verify redirect to market pageawait expect(page).toHaveURL(/\/markets\/test-market/)})
Test File Organization
src/+-- components/| +-- Button/| | +-- Button.tsx| | +-- Button.test.tsx # Unit tests| | +-- Button.stories.tsx # Storybook| +-- MarketCard/| +-- MarketCard.tsx| +-- MarketCard.test.tsx+-- app/| +-- api/| +-- markets/| +-- route.ts| +-- route.test.ts # Integration tests+-- e2e/+-- markets.spec.ts # E2E tests+-- trading.spec.ts+-- auth.spec.ts
Mocking External Services
Supabase Mock
typescript
jest.mock('@/lib/supabase', () => ({supabase: {from: jest.fn(() => ({select: jest.fn(() => ({eq: jest.fn(() => Promise.resolve({data: [{ id: 1, name: 'Test Market' }],error: null}))}))}))}}))
Redis Mock
typescript
jest.mock('@/lib/redis', () => ({searchMarketsByVector: jest.fn(() => Promise.resolve([{ slug: 'test-market', similarity_score: 0.95 }])),checkRedisHealth: jest.fn(() => Promise.resolve({ connected: true }))}))
OpenAI Mock
typescript
jest.mock('@/lib/openai', () => ({generateEmbedding: jest.fn(() => Promise.resolve(new Array(1536).fill(0.1) // Mock 1536-dim embedding))}))
Test Coverage Verification
Run Coverage Report
bash
npm run test:coverage
Coverage Thresholds
json
{"jest": {"coverageThresholds": {"global": {"branches": 80,"functions": 80,"lines": 80,"statements": 80}}}}
Common Testing Mistakes to Avoid
FAIL: WRONG: Testing Implementation Details
typescript
// Don't test internal stateexpect(component.state.count).toBe(5)
PASS: CORRECT: Test User-Visible Behavior
typescript
// Test what users seeexpect(screen.getByText('Count: 5')).toBeInTheDocument()
FAIL: WRONG: Brittle Selectors
typescript
// Breaks easilyawait page.click('.css-class-xyz')
PASS: CORRECT: Semantic Selectors
typescript
// Resilient to changesawait page.click('button:has-text("Submit")')await page.click('[data-testid="submit-button"]')
FAIL: WRONG: No Test Isolation
typescript
// Tests depend on each othertest('creates user', () => { /* ... */ })test('updates same user', () => { /* depends on previous test */ })
PASS: CORRECT: Independent Tests
typescript
// Each test sets up its own datatest('creates user', () => {const user = createTestUser()// Test logic})test('updates user', () => {const user = createTestUser()// Update logic})
Continuous Testing
Watch Mode During Development
bash
npm test -- --watch# Tests run automatically on file changes
Pre-Commit Hook
bash
# Runs before every commitnpm test && npm run lint
CI/CD Integration
yaml
# GitHub Actions- name: Run Testsrun: npm test -- --coverage- name: Upload Coverageuses: codecov/codecov-action@v3
Best Practices
- Write Tests First - Always TDD
- One Assert Per Test - Focus on single behavior
- Descriptive Test Names - Explain what's tested
- Arrange-Act-Assert - Clear test structure
- Mock External Dependencies - Isolate unit tests
- Test Edge Cases - Null, undefined, empty, large
- Test Error Paths - Not just happy paths
- Keep Tests Fast - Unit tests < 50ms each
- Clean Up After Tests - No side effects
- Review Coverage Reports - Identify gaps
Success Metrics
- 80%+ code coverage achieved
- All tests passing (green)
- No skipped or disabled tests
- Fast test execution (< 30s for unit tests)
- E2E tests cover critical user flows
- Tests catch bugs before production
Remember: Tests are not optional. They are the safety net that enables confident refactoring, rapid development, and production reliability.