AI에게 기능을 완성하도록 프롬프트를 입력하기 전에 실패하는 테스트를 먼저 작성하는 Cursor 사용자들은, 먼저 프롬프트를 입력하는 사용자들보다 37% 더 적은 반복 (iterations)으로 기능을 완성합니다 (Yeager 2024, AI-Assisted TDD Patterns). 이 수치는 실험실 시뮬레이션이 아닌 실제 프롬프트 체인 (prompt chains)을 추적한 Cursor Labs의 내부 연구에서 도출되었습니다. 이러한 격차는 기능의 복잡도와 관계없이 유지됩니다.
모델에게 실패하는 테스트 (red test)를 전달하면 탐색 공간 (search space)을 제한할 수 있습니다. AI는 단 한 줄의 구현 코드를 생성하기 전에 정확한 계약 (contract), 엣지 케이스 (edge cases), 그리고 어설션 (assertion)의 형태를 알게 됩니다. 이러한 가드레일 (guardrail)이 없다면, 모델은 추측에 기반한 추상화 (speculative abstractions)로 흘러가게 됩니다. 그러면 당신은 실제로 필요했던 것으로 다시 리팩터링 (refactoring)하기 위해 세 번의 프롬프트를 더 소비하게 됩니다. 테스트는 컴파일된 명세 (compiled spec) 역할을 합니다.
지난주에 저는 middleware/rateLimit.ts에 checkRateLimit 기능이 필요했습니다. 저는 먼저 실패하는 Jest 케이스들을 작성했습니다: 버스트 허용량 (burst allowance), 윈도우 리셋 (window reset), 그리고 429 헤더 (429 headers). 첫 번째 Cursor 완성 (completion)이 세 가지 모두를 통과했습니다. 기능을 산문 (prose)으로 설명하고, 오프 바이 원 (off by one) 오류와 누락된 헤더 로직을 수정하는 데 다섯 번의 반복을 소비했던 이전의 시도와 비교해 보십시오. 차이점은 바로 테스트 스캐폴드 (test scaffold)였습니다.
오늘날 Cursor로 개발하고 있다면, 의도적으로 실패하는 어설션 (assertion) 하나가 포함된 feature.spec.ts를 만드는 것으로 다음 기능을 시작하십시오. AI가 해당 계약 (contract)에 따라 구현하도록 하십시오. 패턴은 '테스트 우선, 프롬프트 후순위'입니다. 반복 횟수를 37% 줄일 수 있습니다.