테스트와 검증이 왜 필요한가?
AI 에이전트를 활용한 바이브 코딩은 주로 '정상적으로 작동하는 1가지의 완벽한 상황'을 위주로 코드를 짜는 경향이 있습니다. 하지만 실제 세상은 예측 불가능합니다.
-
환상의 방어: AI가 작성한 코드는 겉보기엔 완벽해 보여도, 치명적인 논리적 허점이나 존재하지 않는 라이브러리를 호출할 수 있습니다.
-
유지보수 비용의 폭발 방지: 초기 검증 없이 쌓아 올린 코드는 나중에 버그가 발생했을 때 어디서부터 잘못되었는지 파악하기 매우 어렵습니다. (일명 '스파게티 코드'의 파편화)
-
사용자 신뢰 확보: 버튼을 눌렀는데 아무 반응이 없거나, 앱이 튕기는 경험을 한 사용자는 다시 돌아오지 않습니다. 개발자의 속도보다 중요한 것은 사용자의 안정적인 경험입니다.
기능 테스트 "진짜로 작동하는가?"
기능 테스트는 사용자가 기대하는 동작이 실제로 이루어지는지 확인하는 과정입니다. 코드가 아니라 '사용자의 행동'에 초점을 맞춥니다.
핵심 검증 포인트
-
해피 패스: 사용자가 모든 것을 완벽하게 입력했을 때 기능이 정상 동작하는가? (예: 정상적인 이메일과 비밀번호로 로그인 성공)
-
언해피 패스: 사용자가 예상치 못한 행동을 했을 때 시스템이 방어하는가? (예: 비밀번호를 5회 틀렸을 때, 회원가입 시 중복된 아이디를 입력했을 때)
실천 팁: AI에게 코드를 요청할 때 "이 기능의 해피 패스와 언해피 패스 테스트 시나리오를 3개씩 짜줘" 라고 요청하여 검증 리스트를 먼저 확보하세요.
빈값 처리 "아무것도 안 넣으면?"
바이브 코딩으로 만든 서비스가 가장 많이 뻗는 이유 1위는 바로 '빈값(Null/Undefined/Empty)'에 대한 처리 누락입니다.
흔히 발생하는 빈값 사고
-
사용자가 필수 입력 칸을 비우고 '제출'을 눌렀을 때
-
외부 API에서 데이터를 불러오는데 실패해서
null값이 들어왔을 때 -
검색 결과가 '0건'일 때 빈 화면만 덩그러니 남을 때
방어적 프로그래밍 예시
코드를 실행하기 전에 데이터가 유효한지 먼저 튕겨내는 습관이 필요합니다.
// ❌ 바이브 코딩의 흔한 예 (빈값 고려 안함)
function displayUserName(user) {
console.log("환영합니다, " + user.profile.name + "님!");
// user가 null이거나 profile이 없으면 앱이 즉시 종료됨 (Crash)
}
// ✅ 검증이 추가된 코드 (옵셔널 체이닝 및 기본값 활용)
function displayUserName(user) {
const userName = user?.profile?.name || "고객";
console.log(`환영합니다, ${userName}님!`);
}
오류 메시지 표시 방법 "친절하고 명확하게 안내하기"
에러는 피할 수 없습니다. 중요한 것은 에러가 났을 때 사용자에게 어떤 메시지를 보여주느냐입니다. 사용자 화면에 시스템 에러 코드를 그대로 노출하는 것은 최악의 사용자 경험(UX)입니다.
좋은 오류 메시지와 나쁜 오류 메시지 비교
| 상황 | ❌ 나쁜 예 (시스템 중심) | ✅ 좋은 예 (사용자 중심) |
| 로그인 실패 | Error 401: Unauthorized access |
아이디 또는 비밀번호가 일치하지 않습니다. |
| 네트워크 끊김 | AxiosError: Network timeout |
인터넷 연결이 불안정합니다. 잠시 후 다시 시도해주세요. |
| 필수 입력 누락 | Null reference exception at field_2 |
[이름]은 반드시 입력해야 하는 항목입니다. |
| 검색 결과 없음 | (아무 화면도 안 뜸, 무한 로딩) | 검색 결과가 없습니다. 다른 키워드로 검색해보세요. |
오류 메시지 설계 3원칙
-
원인 명시: 무엇이 문제인지 쉬운 언어로 설명합니다.
-
해결책 제시: 사용자가 지금 당장 무엇을 해야 하는지 알려줍니다.
-
책임 전가 금지: 사용자를 탓하는 뉘앙스("잘못된 입력입니다")보다는 중립적인 언어("형식에 맞지 않습니다")를 사용합니다.