SuperAPI AI Directory

vibe-coding-tdd

Coding & development

View repository

Updated 10-15 16:43

About this skill

Vibe Coding — TDD Guide

Enforce test-first development. Cycle: define test → run (fail) → implement → run (pass) → refactor.

Entry Router

Called directly by user (no feature context)?
→ READ: ## Direct Activation

Called by vibe-coding-build with feature context?
→ Detect framework → READ: ## [Framework] Template → output TDD steps

Jump directly to the matching ## [Framework] Template section. Do not read all templates — only the one matching the detected framework.


Direct Activation

1. Read progress.txt — get framework and active feature
2. If missing or no CURRENT_PHASE listed:
   Ask: "What feature are you writing tests for? What framework?
   (e.g. Next.js + Vitest, FastAPI + pytest, Go)"
3. Proceed as if BUILD passed the context

Framework Detection

Node.js/TypeScript:
  vitest in package.json → Vitest
  jest in package.json → Jest
  default → recommend Vitest

Python: pytest in requirements.txt → pytest (default: recommend pytest)
Ruby: default → READ: ## RSpec Template
Go: default → built-in testing package → READ: ## Go Template
Rust: default → built-in #[test] → READ: ## Rust Template

Then READ: ## [Vitest/Jest Template | pytest Template | RSpec Template | Go Template | Rust Template]


Vitest/Jest Template

// tests/[feature].test.ts
import { describe, it, expect, vi } from 'vitest'
import { [functionName] } from '../src/[module]'

describe('[Feature Name]', () => {
  it('should [expected behavior] when [input condition]', () => {
    const result = [functionName]([test data])
    expect(result).toEqual([expected output])
  })
  it('should throw [ErrorType] when [invalid input]', () => {
    expect(() => [functionName](invalidInput)).toThrow('[error message]')
  })
})

Component tests (React Testing Library):

it('calls [handler] when [action]', () => {
  const mockHandler = vi.fn()
  render(<[Component] on[Action]={mockHandler} />)
  fireEvent.click(screen.getByRole('button', { name: '[label]' }))
  expect(mockHandler).toHaveBeenCalledOnce()
})

pytest Template

# tests/test_[feature].py
import pytest
from src.[module] import [function_name]

class Test[FeatureName]:
    def test_[behavior]_when_[condition](self):
        result = [function_name]([input])
        assert result == [expected]

    def test_raises_[error]_when_[invalid](self):
        with pytest.raises([ErrorType]):
            [function_name](invalid_input)

RSpec Template

# spec/[feature]_spec.rb
require 'rails_helper'  # or 'spec_helper' for non-Rails
require_relative '../lib/[module]'  # adjust path

RSpec.describe [ClassName], type: :model do
  describe '#[method_name]' do
    context 'when [valid condition]' do
      it 'returns [expected result]' do
        subject = described_class.new([params])
        expect(subject.[method]).to eq([expected])
      end
    end

    context 'when [invalid condition]' do
      it 'raises [ErrorClass]' do
        expect { described_class.new([bad params]).[method] }.to raise_error([ErrorClass])
      end
    end
  end
end

Run command: bundle exec rspec spec/[feature]_spec.rb


Go Template

// [feature]_test.go
func Test[Feature](t *testing.T) {
    tests := []struct{ name string; input [T]; expected [T]; wantErr bool }{
        {"happy path", [input], [expected], false},
        {"error case", [bad input], [zero], true},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result, err := [Func](tt.input)
            if (err != nil) != tt.wantErr { t.Errorf("err: %v", err) }
            if result != tt.expected { t.Errorf("got %v, want %v", result, tt.expected) }
        })
    }
}

Rust Template

// In the same file (unit tests) or tests/[feature].rs (integration)
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_[behavior]_when_[condition]() {
        let result = [function_name]([input]);
        assert_eq!(result, [expected]);
    }

    #[test]
    #[should_panic(expected = "[error message]")]
    fn test_panics_when_[invalid]() {
        [function_name]([bad_input]);
    }
}

Run command: cargo test


TDD Output

After generating test file, output:

TDD: [Feature Name]
===================
STEP 1 — TESTS WRITTEN: [N] test cases
File: tests/[feature].test.ts

STEP 2 — RUN TO FAIL:
Command: [npm test | pytest | go test ./...]
Expected: All [N] tests FAIL. If any pass without implementation — test is wrong.

STEP 3 — IMPLEMENT:
File to create: src/[module].ts
[Describe expected implementation — do NOT write it yet]

STEP 4 — RUN TO PASS:
Command: [same as step 2]
Expected: All [N] tests PASS. Coverage: [target]%

STEP 5 — VERIFY:
[ ] All tests pass
[ ] No tests skipped
[ ] Coverage meets threshold
[ ] Edge cases covered

Coverage Thresholds

Code type Minimum
Core business logic 80%
API endpoints 70%
UI components 60%
Utilities/helpers 90%

Skip coverage for: UI layout/styling, config files, type definitions, generated code.


Mock Strategy

Mock: external APIs, DB queries (unit tests), file system, time/date, random values. Do NOT mock: the function under test, pure utilities it uses, business logic dependencies.

vi.mock('../src/lib/httpClient', () => ({
  get: vi.fn().mockResolvedValue({ data: { id: 1 } }),
}))

Progress Tracking

After tests written and passing, write to progress.txt:

TDD:
  feature: [name]
  tests_written: [N]
  tests_passing: [N]
  coverage: [N]%