다니엘 르미르, AI 에이전트로 상위 레이어를 지어 코드 품질을 평가하는 '임시 테스트' 제안
- 다니엘 르미르(퀘벡대 TELUQ 교수)가 임시 테스트(ephemeral testing)를 제안함. 원래 코드를 직접 평가하지 않고 AI 에이전트가 그 위에 올린 응용 프로그램을 만들고 테스트하게 한 뒤, 그 결과로 아래층 코드의 품질을 판단하는 방식임.
- 깨끗한 API와 안정된 불변식, 유용한 오류를 갖춘 라이브러리는 에이전트가 빠르게 동작하는 결과물을 만들지만, 숨은 상태나 예상 밖 기본값, 불완전한 문서는 패치와 실패를 쏟아냄. 르미르는 이 실패가 에이전트가 아니라 원래 코드에 대한 증거라고 봄.
- 상위 소프트웨어를 전부 버린다는 점만 빼면 통합 테스트의 한 형태이며, 다른 에이전트와 다른 작업으로 같은 기반을 반복 평가할 수 있음.
- AI로 필요한 걸 그때그때 다시 만들 수 있다는 반론에 대해 르미르는 실용적이지 않다며 어느 정도 안정성이 필요하다고 답함.
- 해커뉴스 댓글에서는 이름이 부적절하다는 지적이 나옴. 회귀 방지에 도움이 안 되니 통합 테스트를 직접 쓰면 된다는 반응과, 커버리지가 아니라 아키텍처 결정을 실험하는 것이라 '임시 빌드아웃'이 맞다는 반응이 갈림.
Hacker News 의견들
이번 달 AI CI 비용 줄였는데 이제 토큰 쓸 데가 또 생겼네. 제일 효과 컸던 건 레포를 직접 읽게 하는 대신 주변 코드까지 포함한 diff를 미리 주는 거였고 비용이 거의 절반으로 줄었음.
나는 이거 꽤 오래 써왔음. 에이전트가 뭘 만들면서 어떤 우회를 했는지 '유저 스토리' 식으로 보고하게 해서 그걸 읽고 다음 변경을 정함.
모노레포에서 NX 쓰는데 affected 기반으로 뭘 돌릴지 정하는 게 좋음. Claude Opus로 관련 e2e 테스트만 골라 돌리니 잘 되더라.
도구 하나 추가된 정도임. 진짜 좋은 테스트는 경계와 한계, 메서드가 바뀌는 지점을 파고드는데 머피의 법칙은 배포 후에나 나타나더라.
솔직히 이러면 slop만 나올 것 같은데. 내 경험상 상황마다 트레이드오프가 달라서 완벽한 답을 받아도 내 실제 사용 사례에 맞는 선택이라는 보장이 없음.
내가 놓친 게 아니라면 회귀 방지에는 도움이 안 됨. 결국 통합 테스트라면 그냥 통합 테스트를 직접 쓰면 되지 않나.
맞음, 통합 테스트를 생성해놓고 왜 버리는지 잘 모르겠음.
'테스트'라는 말이 좀 오해를 부름. 커버리지 얘기가 아니라 아키텍처 결정을 실험하는 거라서 '임시 빌드아웃' 같은 이름이 맞을 듯. 다만 '괜찮다'를 어떻게 판단하는지는 글에 모호함.
나는 API 설계에 이 패턴을 많이 씀. API는 위에 여러 개를 올려봐야 확신이 생기는데 에이전트 덕에 프로토타입 비용이 거의 0이라 확정 전에 다섯 가지 방식으로 써볼 수 있음.
문제는 AI가 '테스트 다 통과했다'고 거짓 보고하는 거임. 막상 그 위에 쌓으려면 기존 flaky 테스트라면서 commit --no-verify를 슬쩍 시도함.
초록 테스트 문제는 뮤테이션 테스트로 잡을 수 있음. 테스트를 테스트하면 초록을 믿을 근거가 생기고 배포 워크플로에 게이트를 두는 것도 방법임.
나는 리팩터링이 잘 됐는지 새 기능 출시로 평가하는 중임. 좋은 리팩터링이면 다운스트림 에이전트가 쓰는 토큰이 줄어야 하는데 아직 큰 차이는 못 봄. 실행마다 분산이 커서 더 돌려봐야 함.
여름에 DSL 만들면서 비슷하게 해봤는데 효과 있었음. 동료 노트북을 초안 DSL로 에이전트가 다시 구현하게 했더니 내가 직접 테스트할 때 못 찾은 문제를 찾아냄.
새로운 얘기 아님. 몇 년째 PR 태그로 옵트인해왔고 지금은 기본으로 켜둠. 읽기 전용 계정이랑 PR 기반 gitops 스킬 파일을 만들어둠.
리처드 가브리엘이 '모든 목적을 예상하고 모든 목적을 잊는 것'이 좋은 추상화의 표식이라고 쓴 게 기억남. LLM은 아직 그 수준은 아니지만 토큰 생성 속도가 빨라서 엔지니어가 머릿속으로 상상하는 걸 실제로 만들어볼 수 있음.
커버리지를 켜고 통합 테스트하는 방법도 씀. 서브에이전트가 앱을 커버리지 켜고 돌려서 리포트를 합치고 커버리지가 안 늘 때까지 반복함.
C/C++ 포인터 API에서 널 처리하고 마지막에만 결과 확인하게 만들어도 Claude는 안전한 게 낫다면서 중간중간 nullptr 검사를 넣어버림.
이건 rule of three의 응용임. 좋은 라이브러리를 쓰려면 클라이언트가 셋은 필요한데 그 셋을 LLM이 만들고 버리자는 제안임.
유도 없는 에이전트는 제일 작은 함수에 단위 테스트를 붙이려 함. AI는 단순 함수에서 실수를 거의 안 하니 구현보다 바깥 레이어, 즉 비즈니스 요구사항을 테스트하는 게 중요함.
근데 하네스를 만드는 경우는? 바깥 레이어에 사람이 들어가는데.