무한 디버그 루프: Cursor CLI가 테스트가 통과할 때까지 수정하게 하기

6 min read

cursor agent가 코드를 자동으로 수정하고 테스트를 실행하고, 실패하면 AI가 다시 수정하게 — 모든 테스트가 통과할 때까지 반복하는 shell 스크립트를 작성합니다. Y/N을 계속 누를 필요 없습니다. 루프를 AI에게 맡겨 두고 다른 일을 하다가, 터미널에 "tests passed"가 나오면 돌아오면 됩니다.

핵심 개념

while tests don't pass:
    run tests → collect error output
    feed error output to cursor agent
    cursor agent fixes the code
    run tests again

“테스트 실행 → 실패 → AI에게 수정 요청 → 반복” 루프를 통과할 때까지 돌리는 구조입니다. 단순하고 직접적이지만 효과적입니다.

1단계: 전제 조건 확인

  • cursor가 설치되어 있고 로그인되어 있음(cursor --version으로 확인)
  • 프로젝트에 터미널에서 실행하는 테스트 명령이 있음. 예:
    • npm test
    • pytest
    • go test ./...
    • cargo test
  • 테스트 실패 시 0이 아닌 종료 코드를 반환함(대부분 테스트 프레임워크는 기본이 그렇습니다)

2단계: 가장 단순한 스크립트

debug-loop.sh를 만듭니다:

#!/bin/bash
 
MAX_LOOPS=10        # max iterations to prevent truly infinite loops
TEST_CMD="npm test" # replace with your test command
loop=0
 
while [ $loop -lt $MAX_LOOPS ]; do
  echo ""
  echo "=== Loop $((loop + 1)) ==="
 
  # run tests and capture stdout + stderr
  TEST_OUTPUT=$(eval "$TEST_CMD" 2>&1)
  EXIT_CODE=$?
 
  if [ $EXIT_CODE -eq 0 ]; then
    echo "✅ Tests passed! Completed in $((loop + 1)) loop(s)."
    exit 0
  fi
 
  echo "❌ Tests failed, letting the AI fix..."
  echo "$TEST_OUTPUT" | tail -30  # print the last 30 lines for your reference
 
  # feed the error output to cursor agent
  cursor agent "Tests failed with the following errors. Please fix the code to make the tests pass:
 
$TEST_OUTPUT" --model gpt-codex-5.3-high --no-interactive
 
  loop=$((loop + 1))
done
 
echo "⚠️  Reached max loops ($MAX_LOOPS). Stopping. Please investigate manually."
exit 1

3단계: 스크립트 실행

chmod +x debug-loop.sh
./debug-loop.sh

이제 커피 마시거나 메시지 답하다가, 터미널에 ✅ Tests passed!가 나오면 돌아오면 됩니다. MAX_LOOPS에 도달했는데도 통과하지 못하면 그때는 사람이 직접 확인할 차례입니다.

4단계: 프로젝트에 맞게 맞추기

테스트 명령 변경(4번째 줄 근처):

TEST_CMD="pytest -x"          # Python, -x stops on first failure
TEST_CMD="go test ./..."      # Go
TEST_CMD="cargo test"         # Rust
TEST_CMD="./vendor/bin/phpunit" # PHP

최대 루프 수 조정:

MAX_LOOPS=5   # conservative, stop early if not improving
MAX_LOOPS=20  # more complex problems get more chances

AI에게 컨텍스트 더 주기(cursor agent 지시 안에서):

cursor agent "Tests failed. Errors below.
The test framework is Jest and the language is TypeScript.
Do not modify test files — only change files under src/.
 
Error output:
$TEST_OUTPUT" --model gpt-codex-5.3-high --no-interactive

개선판: 루프마다 로그 저장

#!/bin/bash
 
MAX_LOOPS=10
TEST_CMD="npm test"
LOG_DIR="debug-logs"
mkdir -p $LOG_DIR
 
loop=0
 
while [ $loop -lt $MAX_LOOPS ]; do
  echo ""
  echo "=== Loop $((loop + 1)) ==="
 
  LOG_FILE="$LOG_DIR/loop-$((loop + 1)).log"
  TEST_OUTPUT=$(eval "$TEST_CMD" 2>&1 | tee "$LOG_FILE")
  EXIT_CODE=${PIPESTATUS[0]}
 
  if [ $EXIT_CODE -eq 0 ]; then
    echo "✅ Tests passed! Completed in $((loop + 1)) loop(s)."
    exit 0
  fi
 
  echo "❌ Failed. Log saved to $LOG_FILE"
 
  cursor agent "Tests failed with the following errors. Please fix the code to make the tests pass:
 
$TEST_OUTPUT" --model gpt-codex-5.3-high --no-interactive
 
  loop=$((loop + 1))
done
 
echo "⚠️  Reached max loops. Stopping. Check the logs in $LOG_DIR/."
exit 1

“어느 루프에서 뭐가 실패했는지” 나중에 보기 좋습니다.

안전 고려사항

위험 완화 방법
AI가 더 많은 파일을 망가뜨림 먼저 git commit으로 상태 저장, 필요하면 git checkout .으로 되돌리기
루프가 너무 많아 쿼터 소모 MAX_LOOPS를 적당히(5–15 권장)
AI가 테스트 파일을 수정함 프롬프트에 “테스트 파일은 수정하지 마라” 명시
루프마다 다른 실패 로그(개선판)를 남겨서 나중에 분석

요약

  1. 스크립트 구조: 테스트 실행 → 실패 → AI에 넘김 → 통과하거나 한도까지 반복
  2. 주요 파라미터: TEST_CMD(테스트 명령), MAX_LOOPS(최대 반복 수)
  3. 프롬프트는 구체적으로: 언어, 수정해도 되는 디렉터리, 테스트 파일은 건드리지 말 것 명시
  4. 먼저 git commit — 문제 생기면 되돌리기 쉽고, 마음 편하게 시도 가능

Worktree와 함께 쓰면 다른 브랜치에서 동시에 디버그 루프를 돌릴 수 있다. 06-cursor-cli-with-worktree 참고.