ssiumha

tdd-practices

Applies TDD workflow to development. Use when writing tests before code, implementing features test-first, fixing bugs via failing test, or refactoring with test coverage. Detects AI anti-patterns.

ssiumha 9 Updated 6mo ago

Resources

2
GitHub

Install

npx skillscat add ssiumha/dots/tdd-practices

Install via the SkillsCat registry.

About this skill

This skill enforces test-driven development (TDD) practices to ensure tests are written before code, detect AI anti-patterns, and maintain test coverage during feature development, bug fixes, or refactoring. It prevents premature optimizations, unauthorized feature additions, and test-driven design flaws by enforcing strict workflow phases and validation checks. Use it when implementing new functionality, fixing bugs via failing tests, or refactoring with test coverage.

SKILL.md

TDD Practices

Phase 1: TDD 세션 시작

새 기능이나 수정 작업 시작 시:

  1. 요구사항 파악

    • 사용자가 요청한 기능을 명확히 이해
    • 모호한 부분은 사용자에게 질문
  2. 테스트 리스트 작성

    • 구현에 필요한 모든 테스트 케이스 나열
    • 단순한 것부터 복잡한 순서로 정렬
    • 사용자에게 목록 보여주고 확인받기
    • 예: "다음 테스트들을 순서대로 진행하겠습니다: 1) ..., 2) ..., 3) ..."
  3. Baseline 확인

    • 기존 테스트 전체 실행
    • 모두 통과하는지 확인
    • 실패하는 테스트가 있다면 먼저 수정
  4. Phase 2 (RED)로 진행


Phase 2: RED - 실패하는 테스트 작성

테스트 리스트의 각 항목에 대해:

  1. 작고 구체적인 테스트 하나 작성

    • 한 번에 하나의 동작만 검증
    • 테스트 이름은 의도를 명확히 표현
    • AAA 패턴 권장 (Arrange-Act-Assert)
    • 테스트 작성 = 설계 활동: 테스트하기 쉬운 인터페이스를 설계
      • 부작용 최소화
      • 의존성 명시적으로 표현
      • 입력과 출력이 명확한 구조
  2. 테스트 실행

    • 작성한 테스트만 먼저 실행
    • 실패 메시지와 이유 확인
  3. 올바른 이유로 실패하는지 검증

    • ⚠️ 테스트가 즉시 통과: 이미 구현이 존재함, 다른 테스트 선택
    • ⚠️ 테스트가 실행 안 됨: 문법 오류, 진행 전 수정 필요
    • 예상한 이유로 실패: 정상, 다음 단계 진행
  4. 실패 출력을 사용자에게 보여주기

    • 어떤 테스트가 실패했는지
    • 왜 실패했는지 (예상값 vs 실제값)
  5. Phase 3 (GREEN)으로 진행


Phase 3: GREEN - 최소 구현

테스트를 통과시키기 위해:

  1. 가장 단순한 코드 작성

    • 하드코딩 허용 (Fake It 전략)
    • 정말 단순하고 명백한 경우에만 일반화된 구현
    • 요청하지 않은 기능 절대 추가 금지 ⚠️
  2. 허용되는 전략

    • Fake It: 하드코딩된 값 반환 (나중에 삼각측량으로 일반화)
    • Obvious Implementation: 구현이 정말 명백한 경우
    • Triangulation: 여러 테스트로 일반화 유도
      → ✨ 여러 테스트를 통과시키다 보면 자연스럽게 범용적 설계가 도출됨
  3. 테스트 실행 → 통과 확인

    • 방금 작성한 테스트 실행
    • 통과하는지 확인
  4. 전체 테스트 실행 → 회귀 없음 확인

    • 기존 테스트들이 여전히 통과하는지 확인
    • 회귀가 발생했다면 즉시 수정
  5. 통과 출력을 사용자에게 보여주기

  6. Phase 4 (REFACTOR)로 진행

GREEN 단계의 AI Red Flags 🚨

다음 징후 발견 시 즉시 중단하고 사용자에게 보고:

  • 🚨 현재 테스트에 없는 기능 추가
    • 예: 로그인 테스트인데 관리자 체크, 로깅 추가
  • 🚨 하드코딩으로 충분한데 반복문/조건문 사용
    • 첫 테스트에서는 하드코딩이 정상
  • 🚨 테스트 수정/삭제로 통과 시도
    • 테스트가 틀렸다면 사용자 확인 필요
  • 🚨 조기 최적화
    • 캐싱, 성능 최적화는 요청받지 않았다면 금지

Phase 4: REFACTOR - 동작 변경 없이 개선

핵심 원칙: 구조 변경과 기능 변경을 절대 섞지 말 것

테스트가 모두 통과한 후:

  1. 코드 냄새 식별

    • 중복 코드 (Copy & Paste)
    • 불명확한 변수/함수 이름
    • 긴 함수
    • 복잡한 조건문
    • 테스트하기 어려운 코드 (설계 재고 신호):
      • 부작용이 많거나 의존성이 강하게 결합된 코드
      • 단일 책임 원칙(SRP) 위반
      • 테스트 작성이 어렵다면 → 함수 쪼개기, 의존성 주입 고려
  2. 한 번에 하나의 리팩토링만 적용

    • Extract Method (메서드 추출)
    • Rename (이름 변경)
    • Remove Duplication (중복 제거)
    • Inline (불필요한 간접 참조 제거)
  3. 각 리팩토링 후 즉시 테스트 실행

    • 모든 테스트가 여전히 통과하는지 확인
    • 실패 시 → 리팩토링 되돌리고 다른 방법 시도
  4. 리팩토링이 끝나면 커밋

    • 깨끗한 상태로 유지

REFACTOR 단계에서 절대 금지 ❌

  • 새 기능 추가: 기능은 다음 RED-GREEN 사이클에서
  • 테스트 기댓값 변경: 동작 변경의 증거
  • 리팩토링과 기능 변경 혼합: 별도 커밋으로 분리
  • 테스트 통과를 위한 코드 수정: REFACTOR는 이미 통과한 상태

REFACTOR 중 테스트 실패 시

테스트가 실패했다면:

  • 리팩토링이 아니라 동작 변경을 했다는 증거
  • 즉시 되돌리기
  • 더 작은 단위로 리팩토링 시도
  1. Phase 5로 진행

Phase 5: 반복 또는 완료

리팩토링 후:

  1. 테스트 리스트로 돌아가기

    • 완료한 테스트 체크
    • 남은 테스트 확인
  2. 다음 단계 결정

    • 남은 테스트 있음 → Phase 2 (RED)로 돌아가기
    • 모든 테스트 완료 → 완료 조건 확인
  3. 완료 조건 확인

    • ✅ 모든 테스트 통과
    • ✅ 중복 코드 제거됨
    • ✅ 의도가 명확함 (이름, 구조)
    • ✅ 예상한 모든 케이스 커버
  4. 필요 시 문서 업데이트

    • 새 기능에 대한 설명
    • API 변경사항 기록

예시

예시 1: Fake It에서 일반화

첫 번째 테스트 + 구현 (Fake It):

def test_add():
    assert add(2, 3) == 5

def add(a, b):
    return 5  # 하드코딩 OK

두 번째 테스트 → 일반화 강제:

def test_add_different():
    assert add(1, 1) == 2  # 실패: assert 5 == 2

# 일반화된 구현
def add(a, b):
    return a + b

전체 테스트 실행 → 모두 통과 ✓


예시 2: AI Red Flag 감지

테스트:

def test_login():
    assert login("user", "pass") == True

⚠️ AI가 생성한 코드 (나쁨):

def login(username, password):
    check_admin_privileges(username)  # 🚨 요청 안 함
    log_access(username)              # 🚨 요청 안 함
    send_notification(username)       # 🚨 요청 안 함
    return True

조치: 즉시 중단하고 사용자에게 보고

⚠️ AI Red Flag 감지:
현재 테스트는 True 반환만 검증합니다.
AI가 요청하지 않은 기능들을 추가하려 합니다:
- 관리자 권한 체크
- 접근 로깅
- 알림 전송

GREEN 단계에서는 테스트 통과에 필요한 최소 코드만 작성해야 합니다.
진행 방법을 선택해주세요:
1. Fake It으로 단순히 True 반환 (권장)
2. 추가 기능을 테스트 리스트에 추가하고 순차 진행

✅ 올바른 코드:

def login(username, password):
    return True  # Fake It OK

상세 참조는 REFERENCE.md를 확인하세요.