“단위 테스트를 생성해줘” — 그 한 줄 뒤에 에이전트가 풀어야 할 진짜 문제
“단위 테스트를 생성해줘.” 수많은 AI 코딩 에이전트가 매일 받는 요청이지만, 이 짧은 문장 뒤에는 에이전트가 스스로 답해야 할 질문들이 줄줄이 따라붙는다. 어떤 코드가 테스트를 필요로 하는가? 이 프로젝트는 어떤 언어와 테스트 프레임워크를 사용하는가? 테스트 파일은 어디에 둬야 하며, CI 파이프라인에서 누락되지 않으려면 어떤 명령으로 실행돼야 하는가? 그리고 무엇보다, 생성된 테스트가 진짜 의미 있는 assertion을 담고 있는가?1
Microsoft가 최근 MIT 라이선스로 공개한 code-testing-generator는 바로 이 질문들에 답하기 위해 설계된 폴리글롯 단위 테스트 에이전트다. 단순히 코드 조각에 대한 테스트를 제안하는 수준을 넘어, 저장소 탐색부터 테스트 계획, 작성, 검증, 그리고 CI 적합성 확인까지 전체 워크플로를 자동화한다는 점에서 GitHub Copilot의 기본 테스트 생성 기능과 궤를 달리한다12.
생성보다 검증: 세 개의 품질 게이트가 만드는 차이
많은 AI 도구는 통과하는 테스트를 만드는 데 능숙하다. 진짜 문제는 그 테스트들이 Assert.NotNull(result) 같은 무의미한 검증으로 채워져 있다는 사실이다. 이런 얕은 assertion은 메서드 본문을 통째로 삭제해도 그대로 통과하기 때문에, 테스트의 존재 이유 자체를 무력화한다.
code-testing-generator의 핵심은 작업 완료 전에 반드시 통과해야 하는 세 가지 품질 게이트에 있다3.
경량 변이 테스트: 코드에 작은 변경을 가했을 때 테스트가 실제로 실패하는지 확인한다. 구현이 바뀌었는데도 테스트가 여전히 통과한다면 assertion이 너무 약하거나 잘못된 것이다.
Assertion 깊이 검사: 결과가
null이 아닌지만 확인하는 얕은 assertion 대신, 실제 동작을 구체적으로 검증하는 assertion을 요구한다.시나리오 매핑 검사: 사용자가 요청한 모든 동작에 대해 일치하는 전용 테스트가 존재하는지 확인한다.
이 게이트들을 모두 통과한 후에야 에이전트는 전체 워크스페이스를 빌드하고 테스트 스위트를 실행한다. 여기서 중요한 설계적 안전장치가 하나 더 추가된다. 저장소의 정상적인 테스트 실행 명령으로 새 테스트를 찾을 수 있는지 확인하는 단계다. 새 테스트 파일이 작성됐지만 CI에서 실행되지 않는 흔한 함정을 원천 차단하는 장치다1.
막연한 요청일수록 빛나는 워크플로의 힘
Microsoft는 152개의 실제 저장소 작업으로 구성된 내부 벤치마크에서 이 에이전트를 평가했다. code-testing-generator는 140개 작업을 완료해 92.1%의 완료율을 기록했고, 동일한 모델을 사용하는 순정 GitHub Copilot은 120개 작업을 완료해 78.9%에 그쳤다1.
특히 눈여겨볼 지점은 프롬프트가 모호할수록 격차가 크게 벌어진다는 점이다. “단위 테스트 생성” 같은 89개의 모호한 요청에서 에이전트는 79개(88.8%)를 완료한 반면, 순정 Copilot은 59개(66.3%)에 머물렀다. 반면 상세한 지시사항이 함께 제공된 작업에서는 두 방식 모두 약 96.8%로 사실상 동률을 기록했다1. 이 차이는 에이전트가 개발자가 프롬프트에 포함하지 않은 리서치, 즉 대상 코드 탐색과 언어·프레임워크 감지, 그리고 작업 범위에 따른 경로 선택(Direct, Single pass, Iterative)을 자동으로 수행하기 때문에 발생한다.
code-testing-generator는 대규모 작업을 만나면 의존성이 적은 코드부터 시작해 복잡도가 높은 코드 순서로 테스트를 계획하고, 각 동작을 테스트 파일에 매핑해 나간다. 이 전략은 작업 범위에 따라 에이전트가 스스로 판단하는 세 가지 실행 경로 중 하나로 구현된다1.
또한 이 이점은 특정 언어나 모델에 국한되지 않는다. Go 작업 15개에서 에이전트는 100% 완료율을 기록한 반면 순정 Copilot은 66.7%에 그쳤고, Claude Opus, GPT-5.5, Claude Haiku 등 여러 모델에서도 워크플로 통합만으로 완료율이 크게 향상됐다1.
우리가 적용할 수 있는 교훈: ‘통과하는 테스트’가 아니라 ‘의미 있게 실패하는 테스트’
code-testing-generator가 전하는 진짜 메시지는 도구 그 자체보다 설계 철학에 있다. AI가 생성한 테스트를 신뢰할 수 있는 유일한 방법은 “테스트가 통과한다”는 사실이 아니라, “코드 변경에 민감하게 실패할 수 있다”는 점을 증명하는 것이다3.
이를 위해 에이전트는 몇 가지 엄격한 원칙을 고수한다. 프로덕션 코드는 절대 수정하지 않으며, 외부 URL 호출, 포트 열기, 정확한 타이밍에 의존하는 취약한 단위 테스트 패턴을 피한다. 또한 통합 테스트, 엔드투엔드 테스트, 브라우저 테스트, 성능 테스트는 현재 범위에서 명시적으로 제외하고 오직 단위 테스트에만 집중한다1. 이 모든 결정은 AI 시대에도 변하지 않는 소프트웨어 테스트의 기본기를 상기시킨다.
dotnet/skills 저장소에서 MIT 라이선스 오픈소스로 제공되는 이 플러그인은 GitHub Copilot CLI는 물론 VS Code에서도 사용할 수 있다1. 그러나 이 도구를 당장 설치하지 않더라도, 핵심 아이디어인 “코드 변경에 민감하게 실패하는 assertion을 확보하라” 는 지금 당장 코드 리뷰에 적용할 수 있는 강력한 기준이 된다.
1From generated code to trusted code with a unit-test agent
2Microsoft releases open-source agent that generates unit tests
3The New .NET Unit-Test Agent’s Best Idea Is Not Writing Tests
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.
