AI 코딩 결과가 자꾸 깨진다면 테스트 자동화부터 점검하세요
AI 코딩 에이전트가 만든 기능은 처음 실행할 때 멀쩡했는데, 다음 수정 이후 로그인이나 결제 화면이 갑자기 깨지는 경우가 있습니다. 프롬프트를 더 길게 써도 같은 문제가 반복된다면 원인은 에이전트의 성능보다 변경 결과를 판정할 테스트 자동화가 부족한 개발 환경에 있을 가능성이 큽니다.
사람에게는 기존 기능을 건드리지 말라는 말이 충분한 지시처럼 들리지만, AI는 어떤 동작이 기존 기능인지 실행 가능한 기준으로 확인해야 합니다. 지금부터 코드 생성 속도를 늦추지 않으면서도 회귀 오류를 줄이는 방법을 실패 원인, 테스트 우선순위, 단계별 적용법, 상황별 운영 방식으로 나눠 살펴봅니다.
AI 코딩 뒤 기존 기능이 깨지는 원인부터 구분합니다
프롬프트 문제가 아니라 검증 기준이 비어 있을 수 있습니다
AI 코딩 결과가 불안정할 때 흔히 하는 첫 대응은 프롬프트에 ‘기존 기능을 절대 변경하지 마세요’라는 문장을 추가하는 것입니다. 그러나 저장소에 테스트가 없거나 테스트 명령이 문서화되지 않았다면 에이전트는 변경 전후의 차이를 객관적으로 판단할 수 없습니다. 화면이 표시된다는 사실만 확인하고 작업을 끝내거나, 컴파일 성공을 기능 정상 작동과 동일하게 해석할 수도 있습니다.
특히 여러 파일에 걸친 수정에서 문제가 커집니다. 회원 정보의 필드명을 바꾸면서 API 응답, 프런트엔드 타입, 데이터베이스 스키마 가운데 두 곳만 수정해도 코드는 빌드될 수 있습니다. 실제 사용자가 예전 계정으로 로그인하는 순간에야 오류가 드러나는 이유입니다. 이때 필요한 것은 더 강한 표현의 지시가 아니라 변경할 때마다 자동으로 실행되는 재현 가능한 테스트입니다.
- 빌드만 성공하는 경우: 타입과 문법은 맞지만 실제 업무 흐름이 검증되지 않은 상태입니다.
- 새 기능만 작동하는 경우: 에이전트가 제공받은 예시 경로만 구현하고 기존 경로를 놓쳤을 가능성이 큽니다.
- 로컬에서만 성공하는 경우: 환경 변수, 운영체제, 시간대 또는 의존성 버전 차이를 의심해야 합니다.
- 간헐적으로 실패하는 경우: 비동기 처리, 테스트 데이터 공유, 실행 순서 의존성을 먼저 확인해야 합니다.
실패 유형을 네 가지로 분류하면 수정 순서가 보입니다
오류 메시지를 곧바로 AI에게 붙여 넣기 전에 재현 조건을 분류해 보세요. 단위 테스트 실패는 작은 함수나 규칙의 문제일 가능성이 높고, 통합 테스트 실패는 데이터베이스·외부 API·인증 계층의 연결을 살펴봐야 합니다. 브라우저 기반 E2E 테스트만 실패한다면 버튼 선택자, 렌더링 대기, 사용자 상태 초기화처럼 화면 환경에 가까운 원인이 많습니다.
- 같은 명령을 두 번 실행해 항상 실패하는지 간헐적으로 실패하는지 확인합니다.
- 이번 변경 파일과 실패한 테스트가 담당하는 기능의 연결 관계를 적습니다.
- 테스트를 단독 실행한 뒤 전체 모음에서도 실행해 순서 의존성을 확인합니다.
- 변경 전 커밋에서도 같은 실패가 발생하는지 비교해 기존 결함과 신규 회귀를 나눕니다.
- 실패 로그, 입력값, 예상값, 실제값을 한 묶음으로 에이전트에게 제공합니다.
에이전트에게 “고쳐 줘”라고만 요청하지 말고 “실패를 먼저 재현하고, 원인을 설명한 뒤, 최소 범위로 수정하고, 같은 테스트를 다시 실행하라”고 지시하세요. 이 순서가 불필요한 코드 변경을 크게 줄입니다.
테스트를 무작정 늘리지 말고 위험한 경로부터 잠급니다
사용자 피해가 큰 기능을 첫 번째 테스트 대상으로 잡습니다
테스트 자동화를 시작할 때 모든 함수의 커버리지를 높이려 하면 시간과 비용이 빠르게 늘어납니다. 작은 프로젝트라면 먼저 로그인, 권한 확인, 주문 생성, 결제 금액 계산, 데이터 저장처럼 실패했을 때 사용자가 즉시 피해를 보는 경로를 선택하는 편이 효과적입니다. 코드 줄 수보다 오류의 영향도와 변경 빈도를 기준으로 우선순위를 정해야 합니다.
예를 들어 쇼핑몰의 상품 카드 색상을 계산하는 유틸리티보다 쿠폰 중복 적용을 막는 규칙이 더 중요합니다. SaaS 서비스라면 소개 페이지의 애니메이션보다 조직별 데이터 격리와 구독 권한을 먼저 검증해야 합니다. 보안 관련 기준을 잡을 때는 코드 보안의 기본 개념도 함께 참고하면 단순 기능 오류와 보안 결함을 구분하는 데 도움이 됩니다.
| 우선순위 | 대상 | 권장 테스트 | 실패 시 영향 |
|---|---|---|---|
| 1 | 인증·권한·결제 | 통합 테스트와 E2E | 정보 노출, 금전 피해, 서비스 차단 |
| 2 | 핵심 계산·상태 전환 | 단위 테스트와 통합 테스트 | 잘못된 결과 저장, 업무 처리 오류 |
| 3 | 외부 API·파일 처리 | 계약 테스트와 실패 응답 테스트 | 연동 중단, 데이터 누락 |
| 4 | 화면 표현·편의 기능 | 컴포넌트 테스트와 일부 E2E | 사용성 저하, 특정 화면 오류 |
정상 경로보다 경계값과 실패 경로가 더 많은 결함을 찾습니다
AI가 생성한 테스트는 입력값 하나와 기대 결과 하나만 확인하는 행복 경로에 치우치기 쉽습니다. 장바구니 수량이 1일 때만 검사하고 0, 음수, 최대 허용량, 재고 초과는 빠뜨리는 식입니다. 테스트를 요청할 때 정상 사례뿐 아니라 빈 값, 중복 요청, 권한 없음, 네트워크 지연, 잘못된 형식도 명시해야 실전에서 의미 있는 방어선이 생깁니다.
- 숫자: 0, 음수, 최댓값, 소수점 반올림, 통화 단위 변경을 검사합니다.
- 문자열: 빈 문자열, 공백만 있는 값, 긴 입력, 이모지와 다국어를 포함합니다.
- 날짜: 월말, 윤일, 자정, 시간대 변경, 만료 시각 직전을 확인합니다.
- 권한: 비로그인, 일반 사용자, 관리자, 다른 조직 사용자의 접근을 각각 검사합니다.
- 외부 연동: 지연, 429 응답, 500 응답, 비정상 JSON, 동일 요청 재전송을 재현합니다.
보안 테스트에서는 성공 여부만 보지 말고 민감 정보가 로그나 오류 응답에 남는지도 확인해야 합니다. 코드 보안 관련 요약 자료를 기준 삼아 입력 검증, 접근 통제, 비밀정보 노출 항목을 테스트 요구사항에 포함하면 좋습니다. 단, 테스트 코드에 실제 운영 API 키나 고객 데이터를 복사하는 실수는 피해야 합니다.
실패를 재현하는 테스트부터 만든 뒤 AI에게 수정을 맡깁니다
빨강에서 초록으로 바뀌는 흐름을 작업 계약으로 사용합니다
이미 발생한 버그를 고칠 때 가장 안전한 순서는 실패를 보여 주는 테스트를 먼저 추가하는 것입니다. 예를 들어 비밀번호 재설정 링크를 두 번 눌렀을 때 서버 오류가 난다면, 동일 토큰의 두 번째 요청이 예측 가능한 오류 응답을 반환해야 한다는 테스트부터 작성합니다. 이 테스트가 수정 전에는 실패하고 수정 후에는 성공해야 해결 여부를 명확히 판단할 수 있습니다.
AI 코딩 에이전트에게도 같은 작업 계약을 적용할 수 있습니다. 재현 테스트를 만들기 전에는 운영 코드를 바꾸지 않도록 제한하고, 테스트가 실제로 실패하는 로그를 확인하게 합니다. 이후 원인 후보와 수정 대상 파일을 설명하도록 한 다음 최소 변경을 수행하게 하면, 증상을 우연히 가리는 임시 처방을 줄일 수 있습니다. 마지막에는 신규 테스트뿐 아니라 관련 테스트 전체를 실행해야 숨어 있는 회귀를 발견할 수 있습니다.
- 재현 조건 고정: 사용한 계정 상태, 입력 데이터, 실행 환경, 요청 순서를 기록합니다.
- 실패 테스트 작성: 현재 버그가 존재할 때 반드시 실패하는 가장 작은 테스트를 만듭니다.
- 실패 확인: 테스트 이름이 아니라 실제 오류 내용이 제보된 증상과 같은지 봅니다.
- 원인 설명 요청: 에이전트가 어떤 코드 경로에서 상태가 잘못되는지 짧게 기술하게 합니다.
- 최소 수정: 관련 없는 포맷 변경이나 대규모 리팩토링을 제외하고 결함만 고칩니다.
- 전체 검증: 단위·통합·E2E 테스트와 빌드, 린트를 순서대로 실행합니다.
좋은 회귀 테스트는 구현 방식보다 사용자에게 보장해야 할 동작을 검증합니다. 내부 함수 호출 횟수만 지나치게 확인하면 리팩토링할 때 테스트가 이유 없이 깨질 수 있습니다.
테스트가 불안정하면 제품 코드보다 격리 조건을 먼저 봅니다
같은 코드인데 통과와 실패가 번갈아 나타나는 플래키 테스트는 AI 코딩 흐름을 특히 혼란스럽게 만듭니다. 에이전트는 실패할 때마다 제품 코드를 조금씩 바꾸려 할 수 있고, 그 결과 원래 정상인 로직까지 손상될 수 있습니다. 실패율이 낮더라도 방치하지 말고 시간, 난수, 네트워크, 공유 데이터, 병렬 실행 여부를 차례로 확인해야 합니다.
무조건 대기 시간을 늘리는 해결책은 피하는 편이 좋습니다. 브라우저 테스트에서 요소가 나타날 때까지 1초를 기다리던 코드를 5초로 바꾸면 당장은 통과할 수 있지만, 느린 환경에서는 다시 실패하고 전체 실행 시간만 길어집니다. 고정 시간 대기 대신 특정 응답 완료, 로딩 상태 해제, 요소의 실제 활성화처럼 관찰 가능한 조건을 기다리게 해야 합니다.
- 현재 시각을 직접 읽는 코드는 고정 가능한 시계 객체로 감싸 테스트합니다.
- 난수와 UUID는 테스트에서 재현 가능한 값으로 주입합니다.
- 각 테스트는 자신이 만든 데이터를 직접 삭제하거나 독립된 데이터베이스 트랜잭션을 사용합니다.
- 외부 API는 무조건 성공 응답만 모의하지 말고 지연과 오류 응답도 계약에 맞춰 준비합니다.
- 테스트 순서를 섞어 실행해 앞 테스트가 남긴 상태에 의존하는 항목을 찾습니다.
- 간헐적 실패를 단순 재실행으로 숨기지 말고 실패 횟수와 환경 정보를 기록합니다.
AI 기반 보안 검증 도구도 발전하고 있지만 자동화 도구의 판정을 그대로 승인으로 간주해서는 안 됩니다. 예를 들어 AI 모의해킹 솔루션 관련 사례처럼 자동 탐지 범위가 넓어져도, 서비스의 권한 구조와 실제 위험도를 이해하는 사람의 검토는 여전히 필요합니다. 기능 테스트, 정적 분석, 의존성 검사, 비밀정보 탐지를 서로 다른 방어선으로 운영하는 이유입니다.
혼자 만드는 앱과 운영 서비스는 서로 다른 검증선을 택합니다
작은 개인 프로젝트라면 세 개의 핵심 흐름부터 고정합니다
사이드 프로젝트나 첫 웹앱을 만드는 독자라면 처음부터 거대한 테스트 체계를 구축할 필요는 없습니다. 사용자가 반드시 거치는 핵심 흐름 세 개를 선정하고, 순수 계산 로직에는 빠른 단위 테스트를, 로그인부터 저장 완료까지는 소수의 E2E 테스트를 두는 방식이 현실적입니다. 무료로 시작할 수 있는 오픈소스 테스트 도구가 많아 별도 사용료보다 초기 설정과 유지 시간 2~6시간 정도를 먼저 예산으로 잡는 편이 정확합니다.
첫 주에는 테스트 개수보다 실행 습관을 만드는 데 집중하세요. 코드 생성 요청 끝에 테스트 명령을 반드시 실행하도록 적고, 실패 로그를 숨기지 않게 하며, 기능 하나를 추가할 때 기존 핵심 흐름이 유지되는지 확인합니다. 배포 전 자동 실행이 어렵다면 로컬 명령 하나로 전체 검증이 가능하게 만드는 것부터 시작해도 충분합니다.
- 로그인 또는 게스트 진입이 가능한지 확인합니다.
- 서비스의 핵심 데이터가 생성·수정·조회되는지 검사합니다.
- 새로고침이나 재접속 뒤에도 저장 상태가 유지되는지 봅니다.
- 권한이 없는 사용자가 다른 사람의 데이터에 접근하지 못하는지 확인합니다.
- 배포 환경과 동일한 런타임 버전에서 빌드가 성공하는지 검사합니다.
사용자와 매출이 있는 서비스라면 배포 차단 기준까지 자동화합니다
반대로 실제 고객이 있고 결제나 민감 데이터를 처리하는 팀이라면 테스트가 단순 참고 자료에 머물러서는 안 됩니다. 코드가 병합될 때 필수 테스트, 타입 검사, 린트, 보안 검사가 자동 실행되고 하나라도 실패하면 배포를 중단해야 합니다. 다만 모든 E2E 테스트를 매 커밋마다 실행하면 피드백이 지나치게 느려질 수 있으므로, 빠른 단위 테스트는 커밋마다 돌리고 전체 브라우저 테스트는 병합 전이나 예약 실행으로 나누는 것이 좋습니다.
운영 장애를 줄이려면 테스트 통과 이후의 안전장치도 필요합니다. 일부 사용자에게만 새 버전을 먼저 노출하는 점진 배포, 오류율이 기준을 넘으면 이전 버전으로 되돌리는 자동 롤백, 기능을 코드 배포와 별도로 끌 수 있는 기능 플래그를 함께 준비하세요. 테스트는 알려진 위험을 막지만 실제 트래픽은 예상하지 못한 입력과 사용 순서를 만들어 내기 때문입니다.
- 필수 통과선: 핵심 단위·통합 테스트와 타입 검사는 예외 없이 통과시킵니다.
- 변경 범위 검사: 수정된 기능과 연관된 테스트를 우선 실행해 빠른 피드백을 얻습니다.
- 보안 검사: 비밀정보, 취약한 의존성, 위험한 입력 처리를 별도 단계로 점검합니다.
- 점진 배포: 내부 사용자나 소수 트래픽에서 오류율과 응답 시간을 관찰합니다.
- 복구 조건: 어떤 수치에서 롤백할지 정하고 담당자가 없어도 실행되게 구성합니다.
- 실패 기록: 장애를 재현하는 테스트를 추가해 같은 문제가 다시 배포되지 않게 합니다.
혼자 빠르게 프로토타입을 만드는 독자라면 핵심 사용자 흐름 세 개와 한 줄짜리 통합 테스트 명령부터 선택하세요. 반면 고객 데이터와 매출을 책임지는 팀이라면 권한·결제·데이터 격리 테스트를 병합 조건으로 설정하고 점진 배포와 롤백까지 하나의 검증선으로 연결하는 선택이 맞습니다.

- 다음글AI 코딩 보안: 에이전트가 개발 파이프라인을 바꾸는 방식 26.08.16
등록된 댓글이 없습니다.
