AI가 코드를 짜도 깨지는 것들: 테스트와 도구 설계의 맹점

AI가 코드를 짜도 깨지는 것들: 테스트와 도구 설계의 맹점

e.preventDefault() 한 줄 누락이 정부 서비스를 멈춘 사건—AI 코드 생성 시대일수록 자동화 테스트가 보지 못하는 것을 인간이 설계해야 한다.

e.preventDefault 접근성 테스트 MCP 설계 키보드 네비게이션 AI 코드 생성 인증 버그 프론트엔드 DX
광고

모든 자동화 테스트가 통과했다. 유닛 테스트, 통합 테스트, E2E 테스트, 보안 리뷰, 사용자 인수 테스트까지. 그리고 롤아웃은 성공적으로 완료됐다. 그런데 정부 서비스 센터 직원들은 로그인을 할 수 없었다. 운전면허 갱신도, 출생·사망 신고도, 재난 지원 시스템 접근도 모두 막혔다. 원인은 e.preventDefault() 한 줄의 부재였다.

dev.to에 공유된 이 인증 버그 사례가 흥미로운 이유는 버그 자체의 기술적 참신함 때문이 아니다. React SPA에서 폼 제출 시 e.preventDefault()를 빠뜨리면 브라우저가 React 이벤트 핸들러를 우회해 기본 폼 제출을 수행한다는 사실은 중급 이상의 프론트엔드 개발자라면 누구나 안다. 문제는 마우스 클릭은 통과하고 키보드 Enter는 실패하는 비대칭 동작이 수많은 테스트를 어떻게 모두 통과했느냐는 것이다.

답은 간단하다. 팀이 테스트를 설계할 때 마우스 인터랙션을 암묵적 기준으로 삼았기 때문이다. 자동화 테스트는 우리가 생각한 시나리오만 검증한다. 키보드만으로 서비스를 이용하는 사용자, 스크린 리더를 사용하는 사용자, 보조 기술에 의존하는 사용자—이들의 인터랙션 패턴은 대부분의 테스트 설계에 등장하지 않는다. 접근성(a11y)은 QA 체크리스트 한 줄이 아니라 테스트 시나리오 자체를 구성하는 방식에서 시작해야 한다는 것을 이 사례는 정확하게 가리키고 있다.

결국 이 팀이 문제를 발견한 방법은 서비스 센터에 직접 나가 사람들이 소프트웨어를 사용하는 모습을 관찰하는 것이었다. 몇 분 만에 패턴이 보였다. 마우스 클릭 성공, 키보드 Enter 실패. 로그 분석과 네트워크 트래픽 리플레이로는 수일이 걸려도 찾지 못한 것을 현장 관찰 몇 분이 해결했다. 프로덕트 사고에서 말하는 '사용자 여정 관찰'이 단순한 UX 리서치 방법론이 아니라 디버깅 전략이 될 수 있다는 것을 이 사례는 증명한다.

AI 코드 생성 도구가 일상화된 지금, 이 이야기는 다른 층위의 의미를 갖는다. Cursor나 Claude로 폼 컴포넌트를 생성하면 e.preventDefault()를 빠뜨리는 일은 오히려 줄어들 수 있다. AI는 자주 쓰이는 패턴에 강하다. 그런데 바로 그것이 새로운 맹점을 만든다. AI가 생성한 코드는 '평균적인 사용 패턴'에 최적화되어 있다. 키보드만 쓰는 사용자, 느린 네트워크 환경의 사용자, 비표준 브라우저를 쓰는 사용자—통계적으로 소수인 이 엣지케이스들은 AI 생성 코드에서도, AI가 함께 작성하는 테스트에서도 체계적으로 누락될 가능성이 높다.

이 관점에서 MCP 서버 실무 평가 글이 제시한 프레임워크가 흥미롭게 겹친다. Promptway의 MCP 서버 평가 기준에서 가장 먼저 살펴보는 항목이 'Auth blast radius'—읽기 전용이 가능한지, 쓰기 권한은 명시적으로 분리되어 있는지다. AI 에이전트가 도구를 통해 세상에 영향을 미치는 시대에, 도구 자체의 설계가 최악의 실패를 어떻게 좁혀두느냐가 핵심 평가 기준이 된다는 것이다. 인증 버그 사례와 구조가 같다. 테스트가 통과해도 설계 자체에 맹점이 있으면 실패는 사용자에게서 온다.

같은 맥락에서 MCP 2026-07-28 스펙의 세션 제거와 명시적 상태 핸들 패턴 전환도 읽힌다. JR Trippett이 소개한 StateForge 패턴의 핵심은 숨겨진 세션 대신 모델이 직접 보고 추적할 수 있는 핸들을 쓴다는 것이다. create_cart() → "cart_7f3a9c2e5b1d". 무엇이 연결되어 있는지 트랜스크립트에서 읽을 수 있고, 잘못됐을 때 어떤 상태가 문제였는지 추적할 수 있다. 이것은 디버거빌리티(debuggability)를 설계 원칙으로 삼는 것이다. 인증 버그 팀이 로그만 봤을 때는 아무것도 보이지 않았고, 사람을 관찰했을 때 패턴이 보인 것과 대칭되는 설계 철학이다.

세 이야기가 함께 가리키는 방향은 하나다. AI가 코드를 빠르게 생성할수록, '무엇을 검증하도록 설계할 것인가'의 책임은 오히려 사람에게 더 무겁게 남는다. 테스트를 작성하는 속도가 빨라진다고 테스트의 커버리지 설계가 자동으로 좋아지지 않는다. MCP 서버를 하루 만에 띄울 수 있다고 권한 설계가 자동으로 안전해지지 않는다. 상태 관리 코드를 AI가 생성한다고 실패 모드 설계가 자동으로 명확해지지 않는다.

실무에서 이를 바꾸려면 세 가지 레이어를 의도적으로 설계해야 한다. 첫째, 테스트 시나리오에 키보드·보조기술·비표준 인터랙션을 명시적으로 포함하라. 접근성은 체크리스트가 아니라 시나리오 목록에 있어야 한다. 둘째, 도구와 에이전트의 실패 모드를 '읽을 수 있게' 만들어라. 로그만으로는 보이지 않는 것이 반드시 존재한다. 트랜스크립트, 핸들, 관찰 가능한 상태—이것들이 디버깅의 실제 레버다. 셋째, 주기적으로 실제 사용자가 소프트웨어를 사용하는 장면을 직접 관찰하라. AI가 만든 코드든 사람이 만든 코드든, 실사용 관찰은 자동화가 대체할 수 없는 검증 레이어다.

e.preventDefault() 한 줄이 정부 서비스를 멈췄다. 모든 테스트를 통과한 코드가. AI 코딩 도구가 이 실수를 줄여줄 수는 있다. 하지만 다음 맹점은 이미 다른 곳에서 형성되고 있다. 도구가 빨라질수록, 우리가 놓치지 말아야 할 것에 대한 설계는 더 선명해야 한다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요