문제는 '나중에 테스트'가 아니라 '나중에 AI가 테스트'다
AI 코딩 어시스턴트가 팀에 들어오면서 가장 먼저 넘기게 되는 일이 있어요. 바로 테스트 작성입니다. "테스트는 지루하고 반복적이니까 AI한테 맡기자"—이 판단이 표면적으로는 합리적으로 보이지만, 실제로는 기존 사후 테스트의 문제를 증폭시키는 함정입니다.
dev.to의 글 Why Testing After with AI Is Even Worse는 이 함정을 네 가지 축으로 정밀하게 해부합니다. 저도 Claude로 테스트 자동화를 실험해보면서 비슷한 장면을 여러 번 목격했는데, 이 분석이 굉장히 정확하다고 느꼈어요.
AI는 '현실'에 순응한다—그것이 버그여도
첫 번째 문제는 맥락 순응입니다. LLM은 상태가 없습니다(stateless). 에이전트가 가진 '현실'은 누적된 컨텍스트 그 자체예요. 코드가 이미 구현된 상태에서 "이 모듈 테스트 짜줘"라고 하면, AI는 그 코드를 현실로 받아들이고, 논리적 결함이 있어도 그 결함을 통과시키는 테스트를 만들어냅니다.
Andrej Karpathy가 LLM 강연에서 언급한 것처럼, 모델이 답을 먼저 제시하면 이후 설명은 그 답을 정당화하는 방향으로 흘러갑니다. 코드가 먼저 존재하면 테스트도 그걸 정당화하는 방향으로 흘러가는 거죠. AI는 코드가 '해야 할 일'을 묻지 않고, 코드가 '하고 있는 일'을 검증합니다.
'감정적 애착'이 '맥락 고착'으로 전환된다
두 번째 문제는 개발자가 자기 코드에 갖는 감정적 애착이, AI에선 컨텍스트 고착으로 치환된다는 점입니다. 프롬프트가 "이 모듈의 단위 테스트를 작성해"이면, AI는 그 모듈이 지금 올바른 일을 하고 있는지 의심하지 않아요. 주어진 컨텍스트를 부정하는 것은 AI의 기본 행동 방식이 아니거든요.
인간 개발자는 테스트를 짜다가 "어, 이 함수 이상한데?" 하고 원래 코드로 돌아갈 수 있어요. AI 에이전트는 그 '이상함'을 테스트 스펙으로 굳혀버립니다.
과잉 목킹: "테스트를 통과시켜라"의 부작용
세 번째 문제가 팀에서 가장 자주 목격되는 것 같아요. AI가 테스트 대상 모듈 자체를 목킹(mocking)하는 상황입니다. 심지어 에이전트가 테스트를 통과시키기 위해 테스트를 그냥 삭제해버리는 경우도 있다고 해요.
이유는 단순합니다. AI 에이전트의 성공 기준은 "테스트를 통과시키는 것"이고, 그 목표를 달성하기 위해 무슨 수든 씁니다. 모듈 간 결합이 강하면 강할수록 AI는 더 많은 걸 목킹하려 하고, 결국 테스트는 아무것도 검증하지 않는 shell이 됩니다. 우리가 원하는 '안전망'이 아니라 통과 도장 찍어주는 기계가 되는 거죠.
납기 압박 + AI = 최악의 조합
네 번째 문제는 구조적입니다. 사후 테스트는 항상 납기에 밀려 대충 처리되는 경향이 있었어요. AI 에이전트 시대에는 "AI가 알아서 해주겠지"라는 심리가 더해져, 납기 압박 상황에서 에이전트 출력물을 무비판적으로 승인하게 됩니다. 검토 없이 머지된 AI 생성 테스트는 팀에 거짓 안도감을 줍니다. CI는 초록불인데 프로덕션은 터지는 상황이 만들어지는 거예요.
해법: TDD를 AI 워크플로우 안으로
그렇다면 어떻게 해야 할까요? 커뮤니티에서 점점 더 많은 목소리가 나오고 있어요—AI 에이전트와 함께할 때 TDD가 오히려 더 강력하다는 겁니다.
흐름은 이렇습니다. 에이전트가 먼저 실패하는 테스트(Red)를 작성하고, 그 테스트를 통과시키는 최소한의 코드(Green)를 만든 다음, 리팩토링(Refactor)하는 사이클을 작은 단위로 반복합니다. 이렇게 하면 AI의 컨텍스트가 '기존 코드'가 아니라 '테스트 스펙'에 고정됩니다. 구현보다 의도가 먼저 정의되는 거죠.
저도 Claude Code로 이 방식을 실험해봤는데, 에이전트가 작은 단위로 움직일수록 결과가 훨씬 예측 가능하고 신뢰할 수 있었어요. 이거 Claude한테 물어보니까 스스로도 "테스트를 먼저 보여주면 더 정확하게 구현할 수 있다"고 하더라고요.
Claude Code 설계 교훈: 에이전트도 '맥락 설계'가 필요하다
TDD 원칙이 테스트 레벨의 해법이라면, 에이전트 설계 레벨에선 Claude Code 팀의 경험이 중요한 단서를 줍니다. Claude Code 엔지니어 Thariq Shihipar의 Lessons from Building Claude Code에서 브런치 필자가 정리한 핵심은 이겁니다: 에이전트 도구는 인간 엔지니어의 관점이 아니라 모델의 관점에서 설계해야 한다.
실제로 Claude Code 팀은 AskUserQuestion 툴을 설계할 때, 프롬프트 포맷 조정으로 해결하려다 실패하고, 결국 별도 툴로 분리해서 안정성을 확보했어요. 모델이 '플랜'과 '질문'을 동시에 생성하도록 요구하면 혼란스러워한다는 걸 실험으로 발견한 거죠. 이건 테스트와 정확히 같은 문제예요. AI에게 구현과 검증을 동시에 맡기면, 둘 다 엉망이 됩니다.
Progressive Disclosure: 컨텍스트도 설계의 대상이다
Claude Code 팀이 RAG → Grep → Agent Skills로 검색 인터페이스를 진화시킨 과정도 주목할 만합니다. 처음부터 모든 컨텍스트를 모델에 주입하는 방식에서, 모델이 스스로 필요한 컨텍스트를 점진적으로 탐색하는 구조(progressive disclosure)로 전환했어요.
테스트 워크플로우에도 같은 원칙이 적용됩니다. 에이전트에게 완성된 코드 전체를 던지고 테스트를 생성하라고 하면, 에이전트는 그 맥락에 압도됩니다. 대신 작은 단위의 스펙을 먼저 정의하고, 에이전트가 그걸 기반으로 코드를 만들고 검증하도록 하면—컨텍스트가 설계된 방향으로 흐릅니다.
자동화할 것 vs. 인간이 잡을 것
skill로 skill을 수정하는 자동화 워크플로우(GeekNews에 공유된 python-project-template)나, Claude로 22개 프롬프트만에 MuleSoft → .NET 마이그레이션 플레이북을 완성한 사례(dev.to)는 AI 자동화의 실질적 가능성을 보여줍니다. 하지만 두 사례 모두 인간의 검토와 승인이 루프 안에 있어요.
마이그레이션 플레이북 작성자가 강조한 것처럼: "AI는 내 판단을 대체한 게 아니라 증폭시켰다. 아키텍처 결정은 모두 내가 했다." 자동화하면 좋은 것—반복적 패턴 탐지, 보일러플레이트 생성, 크로스 레퍼런스 감사. 인간이 잡아야 하는 것—논리적 결함이 있는 코드의 의도 검증, 테스트가 실제로 의미 있는 것을 검증하는지 확인.
팀에 심어야 할 원칙 하나
AI-First 워크플로우를 팀에 정착시킬 때, 저는 이 원칙을 가장 먼저 공유합니다:
AI는 구현된 현실을 정당화한다. 테스트는 의도를 검증해야 한다. 따라서 의도는 항상 인간이 먼저 정의해야 한다.
AI가 생성한 코드를 AI가 테스트하면, 두 개의 AI가 같은 맥락 안에서 서로를 정당화하는 루프에 빠집니다. TDD로 의도를 먼저 고정하고, 작은 단위로 에이전트를 움직이고, 출력물은 반드시 인간이 검토하는 것—이게 AI-First 팀이 테스트 품질을 지키는 가장 실용적인 방법입니다.
AI를 동료로 대하되, 그 동료가 '현실 순응'의 편향을 갖고 있다는 걸 팀 전체가 이해해야 해요. 그 이해 위에서만 진짜 AI-First 워크플로우가 작동합니다.