상담 예약 화면이 정상으로 열렸는데, 예약 현황을 읽지 못한 날에도 모든 시간이 비어 있는 것처럼 보인다면 어떨까요. 방문자는 신청할 수 있다고 믿고 시간을 고르지만, 실제로는 확인이 필요한 상태입니다. 오류 화면이 뜨지 않아도 서비스에는 문제가 생길 수 있습니다.
지난 글 AI로 빠르게 만든 사이트, 운영해 보니 달랐던 것들에서는 이노자일 사이트의 자동 검사를 여러 겹으로 두는 이야기를 했습니다. 이번에는 그 검사를 모두 통과한 뒤의 이야기입니다. 앞서 말한 상담 예약 화면처럼, 오류가 나지 않아도 잘못된 상태를 보여 줄 수 있는 문제들이 남아 있었습니다.
기능을 만든 AI와 별도로 코드를 읽고 의문을 제기하는 AI에게 다시 살펴보게 했습니다. 아래 다섯 가지는 그때 나온 지적입니다. 넷은 코드에서 동작을 확인한 결함이었고, 하나는 데이터가 늘면 집계가 잘릴 수 있는 위험이었습니다.

테스트가 통과했는데 왜 다시 봤을까
자동 테스트는 정해 둔 상황에서 기능이 기대한 대로 움직이는지 반복해서 확인합니다. 버튼이 눌리는지, 신청이 저장되는지처럼 이미 알고 있는 중요한 흐름을 지키는 데 유용합니다. 하지만 처음부터 시험할 상황으로 적지 않은 문제는 놓칠 수 있습니다.
저희는 작업을 마무리할 때 자동 테스트와 별도로 검수 역할의 AI에게 변경된 코드를 읽게 합니다. 이 AI는 파일을 읽을 수만 있고 고치지는 못합니다. 만든 쪽이 내린 판단과 아직 살펴보지 못한 범위도 함께 알려 주고, 이번 변경에서 위험해진 곳을 중심으로 반박해 달라고 요청합니다. 이번에는 글의 공개 상태와 로봇 방문 기록 등 데이터가 오가는 경로가 검수 대상이었습니다.
AI의 지적을 곧바로 결론으로 삼지는 않았습니다. 실제 코드와 기록을 사람이 다시 확인한 뒤 수정할지 결정했습니다.
처음 검수에서 나온 다섯 가지
첫째, 예약 시각이 지나 공개된 글을 내부에서는 여전히 초안으로 보는 구간이 있었습니다. 하루에 한 번 도는 정리 작업이 저장 상태를 바꾸기 전까지, 방문자는 글을 볼 수 있어도 편집 경로는 초안으로 판단했습니다. 그 사이 글을 수정하면 새 내용을 검색 서비스에 알리는 처리에서 빠지고, 수동 발행 시 공개일이 바뀔 수도 있었습니다. 방문자에게 보이는 상태와 관리자가 다루는 상태가 서로 달랐던 것입니다.
둘째, 로봇의 출발지를 확인하는 주소 목록이 새 사본보다 오래된 사본을 우선할 수 있었습니다. 목록을 데이터베이스와 파일 두 곳에 두었는데, 어느 쪽이 최근 것인지 비교하지 않았습니다. 새 목록을 받아 배포해도 예전 목록으로 로봇을 판단할 수 있어 날짜를 비교하도록 고쳤습니다.
셋째, 같은 주소 목록의 출처가 코드 세 곳에 따로 적혀 있었습니다. 지금은 같아 보여도 한 곳만 바꾸면 서로 다른 목록을 보게 됩니다. 한 곳에서 관리하고 다른 곳이 이를 읽도록 정리했습니다. 당장의 화면 오류보다 다음 수정에서 생길 불일치를 막는 일이었습니다.
넷째, 정보를 읽지 못했는데도 정상처럼 보이는 경로가 세 군데 있었습니다. 가장 눈에 띄는 곳은 상담 시간입니다. 예약 설정이나 현황을 읽는 데 실패해도 가능한 시간을 정상 응답으로 내보낼 수 있었습니다. 이제는 확인 실패를 화면에 알리고 다시 시도할 수 있게 했습니다. 다른 두 곳에서는 알림 처리 실패와 로봇 주소 사본 조회 실패가 기록이나 관리자 화면에 충분히 드러나지 않았습니다.
다섯째, 로봇 방문 합계가 데이터가 쌓인 뒤 일부만 셀 위험이 있었습니다. 예전 코드는 한 번에 많은 행을 요청했습니다. Supabase 문서는 기본 반환 상한을 1,000행으로 안내합니다. 다만 저희 운영 프로젝트에 그 상한이 실제로 어떻게 설정됐는지는 직접 확인하지 못했습니다. 당시 기록은 18행이어서 집계가 잘린 일도 없었습니다. 앞으로의 위험으로 보고 여러 번 나누어 끝까지 읽도록 바꿨고, 작은 반환 상한을 흉내 낸 테스트로 합계를 확인했습니다.
다섯 지적은 모두 수정할 이유가 있었지만, 이미 발생한 오류와 앞으로 발생할 수 있는 위험은 다르게 적는 편이 정확했습니다.
고친 뒤에는 무엇을 확인했을까
각 문제를 다시 읽고 수정한 뒤 관련 테스트를 보탰습니다. 특히 오래된 주소 목록을 고르던 경우와 방문 기록이 잘리던 경우에는 수정 전 판단으로 되돌려 새 테스트가 실제로 실패하는지도 확인했습니다. 고장 난 코드를 넣어도 계속 통과하는 테스트라면 문제를 지키지 못하기 때문입니다.

같은 마감 과정에서 가끔 실패하는 화면 테스트도 세 건 만났습니다. 두 건은 개발 서버가 처음 요청을 받을 때 준비하는 시간이 화면의 ‘5초 안에 표시’ 검사에 섞인 경우였습니다. 필요한 서버 응답을 먼저 확인한 뒤 화면을 보도록 순서를 바꾸고, 화면 검사 기준은 그대로 두었습니다.
나머지 한 건은 상담 시간 설정을 바꾸는 테스트와 마지막 빈 시간을 고르는 테스트가 동시에 달린 문제였습니다. 서로 같은 일정을 건드리는 테스트만 차례로 돌도록 했습니다. 이후 전체 검사가 연속으로 통과했지만, 충돌을 일부러 다시 일으켜 수정 전후를 비교한 것은 아닙니다. 확인한 범위와 아직 남은 범위를 구분해 두었습니다.
수정한 코드도 다시 검수했습니다
한 번 고쳤다고 끝내지 않았습니다. 별도의 AI에게 수정한 부분을 다시 읽게 했고, 네 가지 추가 지적을 받았습니다. 그중 두 가지는 특히 기억에 남습니다.
예약 글이 공개됐는지 판단하는 기준을 고쳤는데, 글 편집 화면 한 곳은 여전히 옛 기준을 쓰고 있었습니다. 방문자에게는 공개된 글이 관리자에게는 ‘초안’으로 보이고, 발행 취소 버튼도 숨겨졌습니다. 같은 화면의 다른 표시는 새 기준을 쓰고 있어 한 줄 안에서 두 상태가 어긋났습니다.
또 새로 붙인 테스트 한 건은 실제 수정된 판단을 거치지 않고, 그 판단을 테스트 안에서 손으로 흉내 내고 있었습니다. 수정한 코드를 되돌려도 초록불이어서 잘못을 잡지 못했습니다. 판단을 한곳으로 모으고, 옛 판단으로 되돌리면 테스트가 실패하는 것까지 다시 확인했습니다.
여기서 얻은 교훈은 AI가 만들었으니 AI가 검수해야 한다는 뜻은 아니었습니다. 검사할 상황을 정하는 일, 지적이 사실인지 확인하는 일, 테스트가 정말 그 문제를 잡는지 살피는 일이 따로 필요하다는 뜻이었습니다. 만든 사람이 다시 읽든 다른 개발자가 보든, 같은 기준이 도움이 됩니다.
맡기고 운영할 사이트라면 무엇을 볼까
홈페이지 제작을 의뢰할 때 ‘테스트를 합니다’라는 말만으로는 확인 범위를 알기 어렵습니다. 상담 신청이나 예약처럼 중요한 흐름에서 정보 조회가 실패하면 방문자에게 무엇이 보이는지, 공개 상태와 관리자 화면이 같은 기준을 쓰는지, 새로 발견한 문제를 다음 수정 때 어떻게 다시 확인할지를 물어볼 수 있습니다.
모든 작은 문구 수정에 별도의 검수가 필요한 것은 아닙니다. 저희도 데이터 저장 방식이 바뀌거나 여러 기능의 판단 기준이 함께 바뀔 때 검수를 더합니다. 중요한 것은 검사 횟수보다 무엇을 확인했고 무엇은 아직 추정인지 남기는 일입니다. 이번 다섯 사례를 겪으며, 자동 테스트의 초록불은 작업 종료 신호가 아니라 한 번 더 물어볼 출발점이 될 수 있다는 걸 배웠습니다.