1. AI 역설과 코드 품질의 상관관계
AI 도구를 도입한 많은 조직이 개발 속도는 빨라졌으나 실제 배포 속도는 느려지고 버그가 증가하는 ‘AI 역설’을 경험하고 있습니다. 이는 AI를 아키텍처적 결함을 해결하기 위한 지름길로만 사용했기 때문입니다. 발표자는 AI가 뛰어난 기술을 가졌지만 기억력이 없다는 점을 강조하며, AI가 코드를 제대로 이해하게 하려면 인간에게도 명확한 코드를 작성해야 한다고 주장합니다. 아키텍처적 기능 부채를 안고 AI를 도입하는 것은 더 빠른 버그 생성과 깊은 혼돈을 초래할 뿐입니다.
2. RSpec의 한계와 AI 친화성 저해 요소
기존 RSpec 기반의 테스트 슈트는 다음과 같은 이유로 AI와 인간 모두에게 어려움을 주었습니다.
* 원격 작용(Creepy Action at a Distance): let, subject, 중첩된 describe 블록 등은 코드의 실행 흐름을 선형적으로 파악하기 어렵게 만듭니다. 특정 변수의 정의를 찾기 위해 파일 전체를 탐색해야 하는 구조는 AI의 컨텍스트를 낭비시킵니다.
* 컨텍스트 윈도우 낭비: 수천 줄에 달하는 테스트 파일에서 변수의 정의를 찾기 위해 AI는 불필요하게 많은 정보를 로드해야 하며, 이는 지능 저하와 환각(Hallucination)으로 이어집니다.
* 느린 피드백 루프: 복잡한 설정으로 인해 테스트 실행 속도가 느려지면 AI 기반의 반복적인 수정 및 검증 과정이 비효율적으로 변합니다.
3. Minitest와 Sorbet을 활용한 해결책
발표자는 RSpec 대신 Minitest를 선택하고 Sorbet을 도입하여 다음과 같은 변화를 주었습니다.
* 강력한 타입 시스템(Sorbet): 코드의 의도를 명확히 문서화하여 AI의 환각을 줄이고 IDE의 자동 완성 기능을 극대화했습니다. 이는 인간 개발자가 코드를 읽을 때 변수의 타입을 즉시 파악할 수 있게 돕는 것과 같은 원리입니다.
* 단순한 루비 패턴: let과 같은 마법 같은 기능을 배제하고, 명확한 메서드 호출과 선형적인 코드 구조를 지향했습니다. 파일당 최대 500줄 제한과 명확한 네임스페이스를 적용했습니다.
* 네임스페이스 기반의 헬퍼: helpers.user.create와 같이 구조화된 헬퍼를 통해 기능 발견 가능성을 높였습니다. IDE의 자동 완성을 통해 사용 가능한 헬퍼를 쉽게 탐색할 수 있습니다.
* 프로토콜 버퍼(Protobuf): API 경계에서 타입을 강제하여 백엔드와 프런트엔드 간의 타입 안전성을 확보했습니다.
4. AI를 활용한 점진적 마이그레이션 전략
대규모 코드베이스를 한 번에 재작성하는 대신 AI(Claude)를 파트너로 활용하여 점진적으로 마이그레이션을 진행했습니다. * 철저한 문서화: AI가 따를 수 있는 명확한 원칙(README)과 참조용 API(Reference API)를 작성했습니다. AI는 시스템 프롬프트보다 디렉토리 내의 README를 더 잘 준수하는 경향이 있습니다. * 2단계 마이그레이션: 먼저 레거시 테스트의 의도를 자연어로 요약한 뒤, 이를 바탕으로 새로운 패턴의 테스트 코드를 생성하게 하여 과거의 나쁜 패턴이 전이되는 것을 방지했습니다. * 인간의 개입: AI가 작성한 코드의 로직을 검토하고, 복잡한 사례에 대해서는 인간이 직접 마이그레이션을 수행하며 패턴을 정교화했습니다. 마이그레이션 가이드를 작성하여 팀 전체가 동일한 방식으로 작업할 수 있게 했습니다.