AI가 '테스트 통과' 보고를 믿지 마세요: 종료 코드를 증거로 삼기
요약
AI 에이전트에게 맡긴 테스트 결과 보고서가 실제와 다를 수 있습니다. 화면에 표시된 성공 메시지('Passed')만 믿기보다, 명령어의 '종료 코드(Exit Code)'를 통해 진실을 확인해야 합니다. 종료 코드는 0이 성공, 0이 아니면 실패를 의미하며, 파이프(`| tail`)나 세미콜론(`; echo`) 사용 시 전체 종료 코드가 마지막 명령어에 의해 오염될 수 있으므로 주의가 필요합니다.
핵심 포인트
- 테스트 결과는 화면 메시지보다 '종료 코드'로 판단해야 합니다.
- 파이프(|)나 세미콜론(;)을 사용하면 최종 명령의 종료 코드로 인해 오류가 가려질 수 있습니다.
- AI에게 테스트를 맡길 경우, 실행 명령어와 실제 종료 코드를 반드시 기록하고 검증해야 합니다.
서론
저는 소규모 사업자를 위한 업무 소프트웨어를 혼자 개발하고 있습니다. 개발은 AI 에이전트(Claude Code)에게 맡기고 있습니다.
AI에게 맡기고 테스트를 진행하면, 그 결과는 AI의 언어로 전달됩니다. '테스트가 통과했습니다', '모두 성공했습니다'. 그런데 한 번, 통과했다고 보고된 테스트가 실제로는 실패했던 적이 있었습니다.
이 글에서는 그러한 메커니즘과, 이후 제가 AI에게 지키도록 시킨 것에 대해 작성합니다.
이전 글(Claude Code의 deny만으로는 git push를 막을 수 없는 이야기)의 후속편으로, 이번에는 'AI가 착각하는 것을 어떻게 방지할까'에 대한 내용입니다.
종료 코드란 무엇인가
명령은 끝날 때 **종료 코드(Exit Code)**라는 숫자를 반환합니다. 0이면 성공이고, 0이 아니면 실패입니다. 테스트 도구인 pytest의 경우, 실패한 테스트가 있으면 1을 반환합니다.
화면에 표시되는 '1 failed' 같은 문자는 사람이 읽기 위한 것입니다. AI도 프로그램도, 성공인지 실패인지는 본래 이 종료 코드로 구별합니다.
실패가 성공으로 보였던 두 가지 형태
1. 뒤에 echo를 붙여서 실행한 경우
AI는 테스트를 다음과 같은 형태로 실행했습니다.
pytest tests; echo "EXIT=$?"
'EXIT=1'이 표시되므로, 한눈에 알 수 있습니다. 그런데 ;로 연결된 명령 전체의 종료 코드는 마지막 명령어(echo)의 것이 됩니다. echo는 성공하므로, 전체는 0입니다.
Claude Code는 시간이 오래 걸리는 명령을 백그라운드에서 실행하면, 끝날 때 종료 코드를 알려줍니다. 이 경우에도 그 알림은 '종료 코드 0'이었습니다. AI는 이것을 보고 '통과했습니다'라고 보고했던 것입니다.
2. | tail로 필터링한 경우
출력이 길기 때문에, 마지막 몇 줄만 보려고 하는 형태입니다.
pytest tests | tail -n 1
|(파이프)로 연결하면, 전체의 종료 코드는 보통 마지막 명령어(tail)의 것이 됩니다. tail은 성공하므로, 역시 0입니다. 화면에는 '1 failed'라고 나와 있어도, 종료 코드는 성공하게 되는 것입니다.
직접 확인한 결과
성공하는 테스트가 1개, 실패하는 테스트가 1개인 경우로 시험했습니다(Python 3.14・pytest 9.1, Windows의 Git Bash).
| 실행 방식 | 화면에 표시된 문자 | 전체 종료 코드 |
|---|---|---|
pytest tests | 1 failed, 1 passed | 1(실패) |
| `pytest tests; echo |
검증 보고
- 성공인지 실패인지는 테스트 도구의 종료 코드로 결정합니다. 'N passed' 등의 표시된 줄을 결론으로 삼지 마세요.
- 출력을
| tail나| grep등으로 가공하지 마십시오. 필터링하고 싶다면, 도구 자체의 옵션을 사용하세요.
...
마지막 1줄도 중요합니다. AI에게 맡기고 있으면, 작업 도중에 얻은 테스트 결과를 나중에 코드를 수정한 후에도 '통과했습니다'라고 재사용할 위험이 있습니다. 결과는 현재 코드에 대해 얻은 것만이 증거가 됩니다.
참고로, 이전 글에서 썼듯이 지시 파일(instruction file)은 강제가 아닙니다. AI가 이것을 잊어버릴 수도 있습니다. 그래서 저는 보고서에 '실행한 명령어와 종료 코드'가 없으면 결과를 믿지 않기로 했습니다.
요약
- 종료 코드는 성공 또는 실패의 본래 신호입니다. 0이 성공, 0이 아니면 실패입니다.
- 다만
; echo
이나 | tail
을 붙이면 전체 종료 코드가 마지막 명령어의 것이 되어, 실패가 성공으로 보일 수 있습니다. 화면에 표시된 글자만으로 판단하는 것도 위험합니다. 테스트가 0건이라도 'failed'는 나오지 않습니다.
- '작동하지 않았다'는 성공과 실패를 구분하여 다룹니다.
- AI의 '통과했습니다'는 실행한 명령어와 종료 코드가 갖춰져야 비로소 믿을 수 있습니다.
참고
토론

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기