모든 스킬

test-driven-development (obra/superpowers)

실패하는 테스트를 먼저 작성한 뒤 구현 코드를 쓰는 테스트 우선 방식으로 기능을 만들고 버그를 고칩니다.

superpowers-tdd: 에이전트가 테스트를 먼저 작성하게 만들지만 토큰을 약 1.6배 사용합니다.

추천안전

Codex CLI · gpt-6-astra

24.0 / 30

스킬 없이 대비 향상폭: +1.00 · 추천 · 18회 실행

추천: 총점 24.0/30이 22점 이상, 출력 품질 5.0가 3.5 이상, 향상폭 +1.00가 +1.0 이상입니다.

SOTA

통과

Codex로 테스트

커버 대상 Codex, Claude Code

Codex CLI 0.166 (SOTA 티어): 채점된 실행 18회. 여기서 통과하면 티어 규칙에 따라 Claude Code도 커버되지만, 두 번째 티어에 대해서는 아무것도 말해주지 않습니다.

점수

각 차원은 0~5점이며 여섯 차원을 더하면 30점 만점의 총점이 됩니다. 모든 차원에서 5가 가장 좋습니다. 비용 5는 저렴하고 빠름, 설치 5는 쉬움을 뜻합니다.

트리거 신뢰도
5.0
스킬 없이 대비 향상폭
3.0
출력 품질
5.0
토큰 및 시간 비용
2.0
설치 및 이식성
4.0
안전성
5.0

보안 리뷰

안전

정적 스캔: CRITICAL 0 / HIGH 0 / MEDIUM 0. 수동 검토: 네트워크가 차단된 샌드박스에서 실행 안전(발견 사항 없음). 스캔이 깨끗하다고 해서 스킬이 안전하다는 증거는 아닙니다.

설치

npx skills@latest add obra/superpowers --skill test-driven-development

출처

고정 커밋: 2ce8aa15d05bd57213e6f746f953aafb7ded7a8b

테스트일: 2026-11-02

테스트한 과제

  • 정확한 명세로 함수 구현 — slug.py에 slugify(text, max_length=None)를 구현하세요(Python 3, 표준 라이브러리만 사용). 명세: 텍스트를 소문자로 바꿉니다. ASCII 영문자나 숫자가 아닌 문자가 연속된 구간은 하나의 '-'로 바꿉니다. 앞뒤 '-'는 제거합니다. 결과가 비어 있으면 'n…
  • 작은 상태 저장 클래스 구현 — ratelimiter.py(Python 3, 표준 라이브러리만 사용)에 class RateLimiter(limit, window_seconds, clock=time.monotonic)를 작성하세요. 키별 슬라이딩 윈도 제한기입니다. allow(key)는 최근 window_seconds 동안 기록된 호출이 limit개 미만이면 True를 반환하고 호출을 기록합니다…
  • 반올림 버그 수정 — 고객들은 cart.py의 cart_total이 회계 시스템과 비교해 가끔 1센트 어긋난다고 합니다. 회계 시스템은 각 단계(각 라인 합계, 할인된 소계, 세금)에서 센트 단위로 반올림(half-up)합니다. 예를 들어 cart_total([(1.005, 1)])은 1.09를 반환해야 하며…

장점

  • 스킬 없이보다 평균 점수를 4.0에서 5.0으로 끌어올렸습니다(+1.00).
  • 스킬 이름을 언급하지 않았는데도 적용되었습니다. 스킬 사용군 실행 6/6회에서 스킬 파일을 읽었습니다.
  • 자기 규칙을 한 문장으로 줄인 버전보다 +0.33점 높습니다.
  • 스킬 사용 시 높은 절대 품질: 5.0/5.

단점

  • 스킬 없이보다 토큰을 1.65배 사용합니다.
  • 테스트 참고: 한 문장 프롬프트군(6회 실행)은 나중에 대조군·스킬 사용군과 다른 머신에서 추가한 그룹입니다.
  • 과제·그룹당 n=2이며, 약 1점 미만의 차이는 노이즈입니다.

리뷰

Codex CLI 0.166 (gpt-6-astra, low reasoning)을 Mac 테스트 머신에서 실행했고, 실행마다 새 임시 프로젝트와 임시 HOME/TMPDIR/캐시를 사용했습니다. 스킬 설치(스킬 사용군), 미설치(대조군), 미설치 상태에서 스킬의 핵심 요구사항만 한 문장으로 압축해 프롬프트에 덧붙인 경우(한 문장 프롬프트군)로 나눴으며, 과제·그룹당 2회씩 실행했습니다. 네트워크는 끄고 /tmp 쓰기는 차단했습니다. 프롬프트에는 스킬 이름을 언급하지 않았습니다. 채점은 프로그램 기반(숨은 테스트 / 심어 둔 문제 회수 / 제약 조건 검사 / 해당되는 경우 렌더링+OCR)으로 실행당 0–5점입니다. 어떤 점수도 LLM 심사자가 결정하지 않았습니다.

3개 그룹 비교

그룹평균 점수 (0-5)실행당 토큰
스킬 없음4.065k
한 문장 프롬프트4.67127k
스킬 사용5.0108k

Codex CLI에서 18회 실행해 측정했고, LLM 심사 없이 규칙 기반 검사로 채점했습니다. 총점 24.0 / 30, 판정 추천.

참고: 한 문장 프롬프트군(6회)은 나중에 다른 머신에서 추가되어 대조군·스킬 사용군과 환경이 다릅니다.

판정: 추천 (24.0 / 30). 출처: obra/superpowers, skills/test-driven-development, 커밋 2ce8aa1에 고정. 설치: npx skills@latest add obra/superpowers --skill test-driven-development. 라이선스: MIT(저장소 LICENSE).

무엇인가

obra/superpowers의 test-driven-development 스킬입니다. 설명문에는 "기능이나 버그 수정을 구현할 때, 구현 코드를 작성하기 전에 사용하세요"라고 되어 있습니다. 약 1,500단어의 Markdown(레드-그린-리팩터의 '철칙', 테스트를 건너뛰는 변명 표, 검증 체크리스트)과 좋은 테스트 작성에 관한 추가 파일 하나가 있습니다. 스크립트는 없습니다.

테스트 방법

Codex CLI 0.166(gpt-6-astra, 낮은 추론)을 Mac 테스트 머신에서 실행했고, 실행마다 새 임시 프로젝트와 임시 HOME/TMPDIR/캐시를 사용했습니다. 스킬을 설치한 스킬 사용군, 스킬이 없는 대조군, 스킬 없이 핵심 요구사항을 한 문장으로 압축해 프롬프트 끝에 붙인 한 문장 프롬프트군으로 나눴으며, 작업·군당 2회 실행, 네트워크 차단, /tmp 쓰기 차단 조건이었습니다. 프롬프트에는 스킬 이름을 전혀 언급하지 않았습니다.

  1. 정확한 명세로 함수 구현 — slug.py에 slugify(text, max_length=None)를 구현하세요(Python 3, 표준 라이브러리만). 명세: 텍스트를 소문자로 바꾸고, ASCII 문자나 숫자가 아닌 연속 문자를 하나의 '-'로 바꾸고, 앞뒤 '-'를 제거하고, 결과가 비면 'n…
  2. 작은 상태 저장 클래스 구현 — ratelimiter.py(Python 3, 표준 라이브러리만)에 RateLimiter(limit, window_seconds, clock=time.monotonic) 클래스를 작성하세요. 키별 슬라이딩 윈도 제한기입니다. allow(key)는 지난… 동안 기록된 호출이 limit개 미만이면 True를 반환하고 호출을 기록합…
  3. 반올림 버그 수정 — 고객들은 cart.py의 cart_total이 회계 시스템과 비교해 때때로 1센트 어긋난다고 합니다. 회계 시스템은 각 단계(각 라인 합계, 할인된 소계, 세금)에서 센트 단위로 반올림합니다. 예를 들어 cart_total([(1.005, 1)])은 1.09를 반환해야 하…

채점은 프로그램 방식(숨은 테스트/심어 둔 문제 탐지/제약 조건 검사/해당되는 경우 렌더링+OCR)으로 진행하며 실행당 0~5점입니다. 어떤 점수도 LLM 심사자가 결정하지 않았습니다.

결과

세 번째 군에 제공한 한 문장 프롬프트: "엄격한 레드-그린-리팩터를 따르세요. 먼저 실패하는 테스트를 작성하고 올바른 이유로 실패하는지 확인한 뒤, 통과시키는 최소 구현을 작성하고, 그다음 리팩터하세요. 실패하는 테스트 없이는 프로덕션 코드를 작성하지 마세요."

작업대조군 점수한 문장 프롬프트스킬 사용대조군 토큰한 문장 토큰스킬 사용 토큰스킬 읽음
t1-slugify4.05.05.062k134k108k2/2
t2-ratelimiter4.05.05.063k147k97k2/2
t3-cart-bugfix4.04.05.069k97k116k2/2

평균 점수: 스킬 없음 4.0 vs 스킬 사용 5.0(델타 +1.0). 실행당 토큰: 65k vs 108k(1.65배), 시간 55초 vs 51초. 한 문장 프롬프트군: 4.67(한 문장 프롬프트 대비 스킬의 이득: +0.33, 스킬 없음 대비 한 문장 프롬프트의 이득: +0.67). 한 문장 프롬프트는 실행당 127k 토큰이므로 스킬 비용은 한 문장 프롬프트의 0.85배입니다.

무슨 일이 있었나

  • 정확성은 같았습니다. 두 군의 12회 실행 모두 숨은 테스트 스위트를 통과했습니다(테스트 12/12, 10/10, 11/11). 이런 작은 작업에서는 스킬이 코드의 작동 여부를 바꾸지 않습니다.
  • 바꾸는 것은 작업 순서입니다. 스킬 사용군 6회 모두 테스트 파일이 구현보다 이른 단계에 작성되었습니다. 대조군 6회 모두 에이전트가 테스트와 구현을 같은 패치에 작성했고(또는 cart 작업에서 버그를 먼저 고친 뒤 테스트를 추가했고), 저희가 읽어 본 스킬 사용 실행(slugify)에서는 에이전트가 테스트를 작성하고, 실패하는지 확인하려고 실행한 뒤, 코드를 작성했습니다.
  • 설명문만으로 트리거됩니다. 어떤 프롬프트도 TDD를 언급하지 않았지만 스킬 사용군 6/6 실행에서 스킬 파일이 읽혔습니다.
  • 비용은 더 듭니다. 실행당 토큰이 약 1.65배(107k vs 65k)이고 실제 시간은 비슷했습니다(51초 vs 55초). 에이전트가 스킬과 동반 파일을 읽고 루프를 여러 번 실행하기 때문입니다.
  • 한 문장 버전(엄격한 레드-그린-리팩터, 실패하는 테스트 없이는 프로덕션 코드 금지): 평균 4.67로 대조군(4.0)과 스킬(5.0) 사이였습니다. 실행당 127k 토큰으로 대조군 65k(2.0배), 스킬 108k(스킬의 1.2배)였습니다.
  • 테스트가 구현보다 먼저 작성된 비율은 대조군 6회 중 0회, 한 문장 6회 중 4회, 스킬 6회 중 6회였습니다. 한 문장에서 빠진 두 실행은 cart 버그 수정 작업입니다. 스킬은 매번 그렇게 한 유일한 군이며, 한 문장(실행당 19개)보다 적은 명령(실행당 10개)으로 해냈습니다.

항목별 점수

항목점수이유
1_출력_품질5.0

스킬 사용 시 평균 5.00/5(프로그램 검사, 작업별 표 참고).

2_스킬_없음_대비_향상3.0

스킬 없음 4.00 대비 +1.00점(작업당 n=2, 약 1점 미만은 노이즈).

3_트리거5.0스킬 사용군 6/6 실행에서 스킬 파일을 읽었습니다.
4_지침_이식성4
5_효율성2토큰 1.65배(실행당 108k vs 65k), 시간 0.93배(51초 vs 55초).
6_안전성_및_위생5

이 테스트의 한계

  • 두 군 모두 숨은 테스트를 전부 통과했으므로(천장 효과) 측정된 향상은 결과 차이가 아니라 이벤트 로그에서 계산한 과정 검사(구현 전 테스트 작성)입니다.
  • 작업은 작은 단일 파일 Python 연습문제입니다. 더 큰 저장소, 다른 언어, 테스트 품질(예: 뮤테이션 테스트)은 테스트하지 않았습니다.
  • 작업·군당 n=2: 약 1점 미만의 차이는 노이즈입니다.
  • 규칙 기반 채점은 검사가 볼 수 있는 것만 측정하며, 취향이나 결과가 최선인지는 판단하지 못합니다.

보안

security.md를 참고하세요. 스캔: CRITICAL 0 / HIGH 0 / MEDIUM 0. 판정: 실행해도 안전(네트워크 차단 샌드박스). 깨끗한 스캔 결과가 스킬의 안전성을 증명하지는 않습니다.

결론

말한 대로 합니다. 매번 실패하는 테스트를 먼저 작성한 유일한 군이며(6/6, 대조군 0/6, 한 문장 버전 4/6), 대조군 토큰의 1.7배, 한 문장 버전 토큰의 0.85배를 썼습니다. 이 작은 작업에서 최종 정확성은 모든 군이 같았으므로, 이득은 코드가 아니라 과정에 있습니다.

트랜스크립트

실행 로그: test-driven-development (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.)
열: 작업, 그룹-회차, 점수(0-5), 토큰, 초, 통과한 검사, 에이전트가 연 스킬 파일.

t1-slugify control-1: 점수 4.0, 토큰 62017, 초 55.5, 검사 2/3, 연 파일 없음
t1-slugify control-2: 점수 4.0, 토큰 62139, 초 53.8, 검사 2/3, 연 파일 없음
t1-slugify oneliner-1: 점수 5.0, 토큰 135535, 초 52.9, 검사 3/3, 연 파일 없음
t1-slugify oneliner-2: 점수 5.0, 토큰 134448, 초 46.7, 검사 3/3, 연 파일 없음
t1-slugify treatment-1: 점수 5.0, 토큰 118034, 초 56.3, 검사 3/3, 연 파일 test-driven-development
t1-slugify treatment-2: 점수 5.0, 토큰 97974, 초 48.3, 검사 3/3, 연 파일 test-driven-development
t2-ratelimiter control-1: 점수 4.0, 토큰 63363, 초 46.1, 검사 2/3, 연 파일 없음
t2-ratelimiter control-2: 점수 4.0, 토큰 63431, 초 98.9, 검사 2/3, 연 파일 없음
t2-ratelimiter oneliner-1: 점수 5.0, 토큰 140042, 초 60.8, 검사 3/3, 연 파일 없음

18회 실행, 아티팩트 3개

샘플 출력

SOTA · With the skill: test_slug.py (t1-slugify, run 1, Codex)

import unittest from slug import slugify class SlugifyTests(unittest.TestCase): def test_normalizes_text(self): cases = [ ('Hello, World!', 'hello-world'), (' --ABC__123\t\nxyz!! ', 'abc-123-xyz'), ('café déjà vu 12٣', 'caf-d-j-vu'), ('İ X', 'i-x'), ('already-a-slug', 'already-a-slug'), ] for text, expected in cases: with self.subTest(text=text): self.assertEqual(slugify(text), expected) def test_empty_result_uses_fallback(self): for text in ('', '--- !\t', '中文', '😀'): with self.subTest(text=text): self.assertEqual(slugify(text), 'n-a') def test_length_limits_respect_word_boundaries(self): cases = [ ('Hello, World!', 8, 'hello'), ('Hello, World!', 11, 'hello-world'), ('Hello, World!', 20, 'hello-world'), ('Hello, World!', 5, 'hello'), ('Hello, World!', 6, 'hello'), ('one two three', 7, 'one-two'), ('one two three', 9, 'one-two'), ('Supercalifragilistic', 5, 'super'), ('Supercalifragilistic next', 5, 'super'), ('abc', 1, 'a'), ('abc', 0, ''), ('!!!', 1, 'n'), ('!!!', 2, 'n'), ('!!!', 3, 'n-a'), ] for text, limit, expected in cases: with self.subTest(text=text, limit=limit): self.assertEqual(slugify(text, limit), expected) def test_explicit_none_leaves_length_unlimited(self): self.assertEqual(slugify('Hello, World!', None), 'hello-world') if __name__ == '__main__': unittest.main()

Pro 보기