개발자가 하지 않는 테스트를 쓰는 Rails 테스트 자동화 에이전트 구축
Rails 모노리스의 테스트 공백을 자동 에이전트가 RSpec으로 메운다.
대형 Rails monolith에서는 새 기능 개발이 테스트 작성보다 우선되기 쉽고, 시간이 지날수록 미검증 코드가 쌓이며 디버깅 비용이 커진다. 이를 해결하기 위해 소스 파일을 읽고 RSpec 테스트를 생성·개선한 뒤, 스타일 규칙과 커버리지 목표를 통과할 때까지 스스로 검증하는 자율 에이전트를 만들었다.
에이전트는 Ruby의 동적 타이핑 특성 때문에 테스트 문법 검증도 결국 실행에 의존해야 한다는 점을 전제로 동작한다. Rails 코드베이스에서는 model, serializer, controller, mailer, helper처럼 파일 유형마다 테스트 방식이 다르기 때문에, 각 유형에 맞는 별도 지침이 필요했다. 또한 app/controllers/가 spec/requests/로 가는 경우처럼 예외적인 매핑도 있어, 소스 파일과 spec 파일의 대응 관계를 빠르게 찾는 구조가 중요했다.
재사용 코드가 많은 RSpec 생태계에서는 factory, fixture, 스키마 같은 공유 자산이 핵심 변수였다. factory가 없으면 새로 만들고, 이미 있으면 재사용하되, 여러 테스트에 영향을 주는 공유 파일은 조심스럽게 수정하도록 설계했다.
구현은 Mistral의 오픈소스 코딩 어시스턴트 Vibe 위에서 진행했다. 기본 system prompt는 그대로 두고, 대신 세 가지를 강화했다. repository-level AGENTS.md로 단계별 실행 계획을 강제하고, 파일 위치별 전용 SKILL을 두며, RuboCop과 SimpleCov를 커스텀 도구로 붙였다.
AGENTS.md는 다음 순서를 따르도록 만들었다.
- 소스 파일 읽기
- 문서가 있으면 읽기
- 기존 spec 존재 여부 확인
- 파일 위치에 맞는 skill 1개만 선택해 읽기
- 기존 패턴, factory, helper 찾기
- Extract → Factory → Generate tests 실행
- RuboCop으로 검증
- SimpleCov로 검증
여기에 be_present, be_truthy, be_between, include(:key) 같은 모호한 matcher를 쓰지 말고 eq(exact_value)를 쓰라는 식의 규칙도 넣었다. 또 에이전트가 일부 public method를 빼먹는 문제를 줄이기 위해, 마지막에는 소스 파일을 다시 읽고 "모든 public method를 테스트했는가"를 스스로 점검하도록 강제했다. 이 한 파일만으로 품질 점수가 0.68 → 0.74로 올랐다.
파일 유형별로는 controller용 request spec 같은 전용 skill을 따로 만들었다. 하나의 범용 skill로는 model과 controller를 같은 방식으로 다루기 어려웠기 때문에, 파일 범주마다 별도 지침을 둬 결과를 더 일관되게 만들었다.
RuboCop 도구는 spec 파일을 lint하고, SimpleCov 도구는 RSpec 실행 결과와 커버리지를 함께 돌려준다. SimpleCov가 특히 중요했던 이유는, 테스트가 통과하는지뿐 아니라 어떤 source line이 실제로 실행되지 않았는지까지 돌려줘 에이전트가 자체 수정할 수 있게 해주기 때문이다. 처음에는 생성된 테스트의 약 1/3만 첫 실행에서 통과했지만, 반복 수정으로 실패를 대부분 해결했다.
테스트 품질 평가는 Arrange-Act-Assert 원칙, 정확한 assertion, happy path와 error path의 균형으로 보았다. 하지만 RuboCop 0개, 커버리지 100%, 모든 테스트 통과라는 수치만으로는 좋은 테스트인지 판별할 수 없어서, 별도로 LLM-as-a-judge 점수를 도입했다. "에러 조건이 모두 테스트됐는가", "좋은 테스트인가" 같은 기준을 0~1 사이 점수로 매기게 하되, 채점 기준을 명확히 적어 모델 간 편차를 줄였다.
다만 LLM 점수만으로는 또 다른 문제가 남았다. 테스트가 좋아 보여도 문법 오류로 아예 실행되지 않을 수 있기 때문이다. 예를 들어 User.new(의 닫는 괄호 하나가 빠진 테스트는 구조는 훌륭해 보여도 실제로는 실패한다. 그래서 최종적으로는 실행 가능성 검증과 커버리지 검증이 함께 돌아가야 하며, 에이전트는 다수의 파일을 병렬로 처리하면서 CI/CD 안에서 사람 개입 없이 테스트 공백을 메우도록 설계됐다.
이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.
요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.