tdd-general
Skill2 starsChanged 5 months agoMITView on GitHub
Use this skill for **framework-agnostic TDD** workflows — pure logic, backend services, CLI tools, data pipelines, libraries — where Testing Library / RTL conventions do not apply (keywords: "TDD without React", "백엔드 TDD", "library TDD", "pure function TDD"). Runs the same 5-phase TDD discipline (Intent Interview → Outline → Failing Test → Implement → Refactor + Intent Preservation) but with stack-neutral guidance (Arrange-Act-Assert, given-when-then, table-driven tests, property-based optional). Do NOT trigger when the user is working on React/Vue components — `tdd-first` covers FE-specific RTL conventions.
In this repository7 other files it gives its agents.
- asset-factorySkill
- cfh-harnessSkill
- debug-investigatorSkill
- grillingSkill
- refactoring-strategySkill
- skill-authorSkill
- tdd-firstSkill
The file
Files
TDD-General Workflow
트리거 조건 (컨벤션 — 본문 참고용, frontmatter description이 권위)
TRIGGER: non-FE intent TDD (새로 만든다) — '백엔드 TDD', 'library TDD',
'pure function TDD', 'TDD without React', 'CLI TDD',
'mobile TDD', 'embedded TDD', 'ML 학습 step TDD'.
SKIP: React/Vue 컴포넌트 → tdd-first.
기존 non-FE 파일 *보강*만 (artifact mode) → /cfh-tc-gen 명시 호출 권장.
INTENT vs ARTIFACT:
intent (새 모듈·핸들러·CLI 명령) → tdd-general 자동 트리거
artifact (기존 *.go·*.py·*.swift 보강) → 자동 트리거 약함, /cfh-tc-gen 명시 호출 권장
EXAMPLES:
- 'FastAPI 엔드포인트 TDD로' → tdd-general의 Arrange-Act-Assert 가이드
- 'CLI 도구 TDD' → table-driven test 권장
- '기존 retry.go 테스트 보강' → /cfh-tc-gen 라우팅 권장 (intent 아님)tdd-first의 5 Phase 구조를 그대로 따르되, 테스트 라이브러리·관용구가 stack-neutral한 버전입니다. 백엔드 서비스·CLI·라이브러리·순수 함수·데이터 파이프라인 등 React/Vue가 끼지 않는 영역에서 사용합니다.
tdd-first와 차이
| 영역 | tdd-first | tdd-general (이 스킬) |
| 가정 스택 | React/Vue + RTL + jest/vitest | 임의 (Node·Python·Go·Rust + 임의 테스트 러너) |
| Phase 0 Scope Q1 단위 | "함수 / 컴포넌트 / 기능 / 페이지" | "함수 / 모듈 / 엔드포인트 / 워크플로" |
| Test Outline 형식 | describe('X') { it('renders Y') } | Arrange-Act-Assert 또는 given-when-then. 표(table-driven) 테스트 권장 |
| 쿼리·선택 | getByRole > getByLabelText 등 RTL 우선순위 | N/A (DOM 없음) |
| 인터랙션 | userEvent | 함수 호출, HTTP 요청, CLI 인자 |
| 모킹 | MSW (HTTP), vi.mock | 의존성 주입 우선, 어쩔 수 없을 때만 mock 라이브러리 (sinon·unittest.mock 등) |
| 비동기 | findBy / waitFor | async/await + assertion 직접 |
| 안티패턴 | DOM class 직접 검증, 내부 state 접근, 렌더 횟수 카운팅 | 내부 private 메서드 직접 호출, 시간 의존 (Date.now), 글로벌 상태 누수 |
활성화 시 반드시
- (z) 모르겠음 fallback. 모든 인터뷰 질문에
(z) 모르겠음옵션 기본 탑재. 선택 시~/.claude/skills/asset-factory/references/unknown-answer-playbook.md의 3단계 처리. - 테스트 러너 파악 우선.
package.json·pyproject.toml·Cargo.toml·go.mod등에서 테스트 도구 확인. 감지 안 되면 사용자에게 명시 질문. - stack-neutral 표현 사용. "describe/it" 강제 안 함. Python이면 pytest fixture, Go면
t.Run, Rust면#[test]등 그 스택의 관용구 따름.
Phase 복귀 규칙 (공통)
Phase 2 이후에 초반 답변이 틀렸다고 판단되면:
- "scope 재조정" → Phase 0 복귀
- "intent 재인터뷰" → Phase 1 복귀
- "outline 수정" → Phase 2 복귀
5 Phase (tdd-first 동일)
Phase 0: Scope Narrowing (작업 단위·테스트 계층·커버리지 목표 좁힘)
↓
Phase 1: Intent Interview (의도 6 질문 — Happy Path·Edge·Error·Out-of-scope·관찰 방법 등)
↓
Phase 2: Test Outline (테스트 케이스 제목·구조 제안 → 사용자 승인)
↓
Phase 3: Failing Tests (구현 파일 본문 접근 금지, 시그니처만 확인)
• 정적 타입 언어(Rust·Go·Java·Kotlin·TypeScript): 컴파일 실패도 RED의 일부.
"테스트 실패" vs "구현 미완"을 구분하려면 `unimplemented!()` / `panic!("TODO")` /
`throw NotImplementedError` 등으로 명시 — 컴파일은 통과시키고 런타임에 fail.
↓
Phase 4: Implementation (최소 구현으로 GREEN, hard-code 금지, 테스트 수정 금지)
↓
Phase 5: Refactor + Intent Preservation (리팩터링 + Phase 1 답변 재확인)각 Phase의 절차·원칙은 tdd-first 본문과 동일. 차이는 예시·관용구·라이브러리 가정입니다.
Fast path — Draft-and-Confirm (tdd-first Phase 1 동일): 신호 충분하면(6답 과반 [verified]/[inferred]) 빈 질문 대신 채워진 초안을 제시하고 틀린 것만 정정받는다. 초안 yes면 Phase 1.5 별도 출력 생략(카드가 겸임). 과반 [guessed]면 순차 인터뷰로.
의도 헤더 (tdd-first Phase 3 동일 — 테스트 파일 작성 시 기본 포함, 별도 질문 불필요, 단 형식은 스택 관용 주석): JSDoc은 JS 컨벤션이므로 해당 언어의 관용으로 — Python docstring, Go 함수/패키지 주석, Rust /// doc comment, Java/Kotlin Javadoc/KDoc 등. 내용 구조(목표/happy/edge/error/out-of-scope/관찰)는 동일. 역할은 요약(목차) — 테스트 본문과 어긋나면 테스트가 진실, 헤더는 즉시 갱신 대상.
Phase 1.5 — Final Intent Confirm (Phase 2 진입 직전)
tdd-first와 동일하게 Phase 1 6 답변을 합산 해석·모호 발화 검사·답변 충돌 자가검증 후 명시 yes 받기 (→ ~/.claude/commands/references/final-confirm.md).
non-FE 도메인 동음이의어 예시 (감지 시 명시):
- "service" → Spring
@Servicebean / OS daemon / domain service / SaaS service - "controller" → Spring MVC
@RestController/ domain controller / hardware controller - "client" → HTTP client / DB client / SDK consumer / end-user
- "API" → REST endpoint / library API surface / gRPC stub / public method
- "event" → Kafka event / domain event / lifecycle event / analytics event
검증 게이트 (tdd-first 동일):
- Happy Path / Edge Case / Error Cases / Out of scope 4 카테고리 모두 답
- 관찰 방법 명확
- Phase 0 Scope와 정합
답변: yes (Phase 2 진입) / 정정 <Q번호> / 처음부터 (Phase 0 회귀) / pass. 짧은 동의는 ambiguous로 대기.
스택별 Test Outline 예시
대상 스택의 관용구 예시(Node·Python·Go·Rust·JVM)는 references/stack-examples.md — Phase 2에서 해당 스택 것만 읽기 (lazy load).
안티패턴 (tdd-general 전용)
| ❌ Do NOT | 대신 |
| 내부 private 함수·메서드 직접 호출 | public 인터페이스로만 검증 |
Date.now() / time.time() 직접 사용 | 시간을 인자로 주입 또는 mock |
| 글로벌 상태 의존 (env var, singleton) | 의존성 주입 |
| 테스트 간 상태 공유 (file fixture를 mutate) | 각 테스트 독립 setup/teardown |
| HTTP·DB 실제 호출 | mock·stub 또는 격리된 test container |
| 출력 형식 자체를 assertion (e.g., 줄바꿈 위치) | 의미 있는 필드·값만 |
테스트 품질 (좋은 테스트 — 스택 무관 부분)
오버핏 방지와 별개로 "좋은 테스트 자체"의 원칙 (→ commands/references/test-quality.md). DOM·RTL 쿼리는 N/A, 나머지는 그대로 적용:
- 리트머스: 구현 바꿔도 행동 같으면 green 유지 (public 인터페이스·반환·부작용 결합, 내부 결합 금지)
- 피라미드: 순수 함수로 될 걸 통합·E2E로 올리지 않음 (싼 계층 우선)
- 부작용 테스트: 커넥션 close·트랜잭션 롤백·이벤트 발행·goroutine/async 취소·파일 핸들 해제 — 명시 검증. 실제 버그는 회귀 테스트로 고정
- 의도 명시: 이름=보장 행동 한 문장 / 회귀·table-driven(parametrize)·비직관 setup만 한 줄 주석 / 미커버 영역(통합·실제 라이브러리) JSDoc
- 시간·랜덤·네트워크 고정 (위 안티패턴 표와 일관)
Property-Based Boost (선택)
순수 함수·파서·reducer·정렬 등 수학적 속성이 명확한 코드에는 property-based 테스트 추가:
import fc from 'fast-check';
it('property: parseDate(formatDate(d)) === d', () => {
fc.assert(fc.property(fc.date(), (d) => {
expect(parseDate(formatDate(d))).toEqual(d);
}));
});from hypothesis import given, strategies as st
@given(st.text())
def test_serialize_deserialize_is_identity(s):
assert deserialize(serialize(s)) == suse proptest::prelude::*;
proptest! {
#[test]
fn parse_format_roundtrip(d: i64) {
let s = format_date(d);
prop_assert_eq!(parse_date(&s).unwrap(), d);
}
}// JVM (Kotest property-based)
class SerdeProperty : StringSpec({
"serialize then deserialize is identity" {
checkAll<String> { s ->
deserialize(serialize(s)) shouldBe s
}
}
})references
references/stack-examples.md— 스택별 Test Outline 예시 (Node·Python·Go·Rust·JVM)
이 스킬은 SKILL.md 자체로 완결됩니다. 추가 참조가 필요하면:
~/.claude/skills/tdd-first/references/intent-interview-template.md— 6 질문 템플릿 (FE 예시이지만 일반화 가능)~/.claude/skills/tdd-first/references/anti-overfit-rules.md— 오버핏 방지 5룰 (전부 일반)~/.claude/skills/tdd-first/references/scope-narrowing.md— Phase 0 7 질문 (대부분 일반)
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

