AI 시대의 테스트와 품질

AI가 코드를 쓰는 시대에, 테스트는 선택이 아니라 생존이다.

by 대협
TDD가 더 중요해진 이유
AI 출력의 불확실성

바이브 코딩의 가장 큰 역설은 여기에 있다. AI가 코드를 빠르게 생성해주기 때문에 개발 속도는 극적으로 향상되었지만, 그 코드의 정확성에 대한 확신은 오히려 낮아졌다. 전통적 개발에서 개발자가 직접 한 줄 한 줄 작성한 코드는 그 자체로 개발자의 의도를 반영했다. 하지만 AI가 생성한 코드는 개발자의 의도를 '해석'하여 만들어낸 결과물이다. 이 해석 과정에서 미묘한 오류, 엣지 케이스 누락, 혹은 전혀 예상치 못한 동작이 발생할 수 있다.

필자의 경험: 42개 이상의 바이브 코딩 프로젝트를 수행하면서, AI가 생성한 코드가 '첫 시도에서 완벽하게 동작한' 경우는 전체의 약 30%에 불과했다. 나머지 70%는 한글 인코딩 깨짐, 예외 처리 누락, API 응답 형식 불일치 등 크고 작은 문제가 있었다. 이것은 AI의 한계가 아니라 AI 시대 개발의 본질적 특성이다. 문제는 이러한 오류를 얼마나 빠르고 체계적으로 발견하느냐에 있다.

Gemini_Generated_Image_5n1l3x5n1l3x5n1l.png

특히 주목해야 할 것은 AI가 생성한 코드의 오류 유형이 전통적 개발과 질적으로 다르다는 점이다. 전통적 개발에서의 오류는 대부분 구문 오류나 명확한 로직 오류여서 컴파일러나 기본적인 실행 테스트로 발견할 수 있었다. 반면, AI 생성 코드의 오류는 구문적으로는 완벽하지만 의미적으로 잘못된 경우가 많다. 코드가 컴파일되고 실행도 되지만, 개발자의 의도와 다르게 동작하는 것이다.

회귀 방지의 필수성

바이브 코딩의 핵심 특성 중 하나는 빠른 반복(Iteration)이다. 바이브 코딩에서는 기능을 추가하고 수정하는 사이클이 수 분 단위로 반복된다. 문제는 이 빠른 반복 과정에서 이전에 동작하던 기능이 깨지는 '회귀(Regression)'가 발생할 확률이 전통적 개발보다 훨씬 높다는 것이다.

실전 사례 --- 블랙야크 100대명산 프로젝트: 이 프로젝트에서 산림청 데이터와 국립공원공단 데이터를 병합하는 작업을 진행할 때, AI에게 데이터 매핑 로직을 수정하도록 요청했다. AI는 새로운 매핑 로직을 잘 구현했지만, 기존에 동작하던 GPX 파일 변환(convert_gpx.py) 로직의 좌표 계산 부분이 영향을 받아 일부 산의 등산로가 표시되지 않는 문제가 발생했다. 만약 기존 기능에 대한 테스트가 있었다면, 이 회귀를 즉시 감지할 수 있었을 것이다. 프로젝트 회고에서 '테스트 코드를 작성하지 못한 것이 아쉽다'고 기록한 이유가 바로 이것이다.

회귀 방지가 바이브 코딩에서 특히 중요한 이유는 AI의 '맥락 제한' 때문이다. AI와의 대화가 길어지거나 새 대화를 시작하면, 이전 대화에서 합의한 설계 결정이나 엣지 케이스 처리 방법이 소실될 수 있다.컨텍스트 엔지니어링이 이 문제를 완화해주지만, 완전히 해결하지는 못한다. 테스트는 이 맥락 소실에 대한 가장 확실한 안전장치이다.

리팩토링의 안전망

명세 주도 개발(SDD)의 핵심 장점 중 하나는 같은 명세에서 여러 구현을 실험할 수 있다는 것이었다. Code Review Assistant 프로젝트에서 동일한 '8개 카테고리 리뷰 명세'를 기반으로 PySide6 + Ollama 오프라인 버전, Antigravity 다국어 버전, 웹 기반 LLM 버전의 세 가지를 만든 사례가 대표적이다.

이처럼 구현을 교체하거나 기술 스택을 변경하는 리팩토링은 바이브 코딩에서 빈번하게 일어난다. Seoul Location Services App에서 Streamlit 프로토타입을 React+TypeScript 프로덕션 버전으로 전환한 것도 같은 맥락이다. 이때 테스트가 없다면, 리팩토링 후 기존 기능이 동일하게 동작하는지 확인할 방법이 '직접 눈으로 확인하는 것'밖에 없다. 9개의 서울시 API 엔드포인트를 모두 수동으로 테스트하는 것은 비현실적이다.

새로운 TDD 워크플로우
Spec → Test → AI Implementation

전통적 TDD(Test-Driven Development)의 워크플로우는 Test → Implementation → Refactor였다. 바이브 코딩 시대에는 이 워크플로우가 한 단계 더 확장된다. 명세가 테스트의 기반이 되고, 테스트가 AI 구현의 기준이 되는 3단계 파이프라인이다.

Gemini_Generated_Image_9ayqu49ayqu49ayq.png

이 워크플로우의 핵심 통찰은 '테스트가 AI에 대한 명세'라는 것이다. AI에게 '로그인 기능을 만들어줘'라고 하면 모호하지만, '이 10개 테스트 케이스를 모두 통과하는 로그인 기능을 만들어줘'라고 하면 명확하다. 테스트는 인간의 의도를 AI가 오해할 여지를 최소화하는 가장 구체적인 형태의 명세이다.


Gemini_Generated_Image_k2fgo8k2fgo8k2fg.png
Red-Green-Refactor with AI

전통적 TDD의 Red-Green-Refactor 사이클은 바이브 코딩 환경에서도 유효하다. 다만, 각 단계의 주체와 방법이 달라진다.

Gemini_Generated_Image_v4nz0ev4nz0ev4nz.png

여기서 주목할 점은 Refactor 단계이다. 전통적 TDD에서 리팩토링은 '용기가 필요한' 작업이었다. 코드 구조를 바꾸면 어디서 문제가 생길지 몰랐기 때문이다. 바이브 코딩에서는 AI가 리팩토링을 수행하고 테스트가 여전히 통과하는지 확인하면 된다. 이 과정이 수 분 만에 완료된다. 테스트가 '안전망'이 되어 AI의 리팩토링을 자신 있게 수용할 수 있게 해주는 것이다.

AI가 테스트를 작성하게 하기

바이브 코딩의 흥미로운 역전 중 하나는 AI에게 테스트 작성을 맡길 수 있다는 것이다. 하지만 이것은 양날의 검이다. AI가 생성한 코드를 AI가 생성한 테스트로 검증하면, 같은 오해가 코드와 테스트 양쪽에 반영될 위험이 있다.

필자의 접근법 --- '상호 견제(Cross-Check)' 패턴: AI에게 테스트를 작성하게 할 때는 반드시 인간의 검증을 거친다. 구체적으로는 세 가지 전략을 사용한다.

Gemini_Generated_Image_uz2tbguz2tbguz2t.png

특히 2번 전략 --- '다른 AI로 검증' --- 은 필자가 C# Code Reviewer 프로젝트에서 직접 구현한 패턴이다. AI가 코드를 생성하고, 다른 AI(Phi-3-mini 또는 GPT-4o)가 그 코드를 8개 카테고리로 리뷰하는 구조이다. AI를 활용하되 AI를 견제하는 이 '상호 검증' 패턴은 '보안 감각'의 현대적 구현이라 할 수 있다.

토요일 연재
이전 09화SSD 철학 구현 워크플로우 도구