AI로 API 테스트를 자동화했습니다 — 실제로 효과가 있었던 방법들
요약
AI를 활용하여 API 테스트 스위트를 자동 생성하고 유지 관리하는 실전 워크플로우를 소개합니다. 단순 프롬프팅의 한계를 넘어 도구 증강 생성과 리뷰 루프를 통해 테스트 통과율을 95%까지 높인 경험을 공유합니다.
핵심 포인트
- LLM은 API 구조를 환각할 수 있으므로 실제 스키마 검증이 필수적임
- 가공된 요약 정보를 제공하는 도구 증강 생성 방식이 효과적임
- 피드백 루프를 통한 반복적 개선이 테스트 통과율을 극대화함
- 명세가 모호한 에지 케이스는 여전히 수동 관리가 필요함
AI로 API 테스트를 자동화했습니다 — 실제로 효과가 있었던 방법들
지난 한 달 동안 AI가 나의 API 테스트를 작성하고 유지 관리하도록 만드는 데 시간을 보냈습니다. 단순히 "테스트 데이터 생성"을 말하는 것이 아닙니다. 저는 AI가 나의 API를 이해하고, 실제 테스트 스위트 (test suites)를 작성하며, 엔드포인트 (endpoints)가 변경될 때 이를 최신 상태로 유지하기를 원했습니다.
실제 코드와 실제 실패 사례를 바탕으로 제가 배운 점들을 공유합니다.
내가 해결하려 했던 문제
저는 사용자 관리, 결제, 웹훅 (webhook) 전달을 위한 엔드포인트를 노출하는 API를 관리하고 있습니다. 규모가 아주 크지는 않지만(약 40개의 엔드포인트), 새로운 기능을 추가할 때마다 테스트를 업데이트하는 데 3060분이 소요되었습니다. 이를 한 달에 45개의 기능으로 곱하면 상당한 시간이 됩니다.
저는 다음과 같은 작업을 수행할 수 있는 AI 워크플로우 (workflow)를 원했습니다:
- 나의 OpenAPI 스펙 (spec) 읽기
- 실제로 통과하는 테스트 스위트 (test suites) 생성
- 스펙이 변경될 때 테스트 업데이트
- 내가 놓칠 수 있는 에지 케이스 (edge cases) 포착
시도 1: 채팅창에 OpenAPI 스펙을 통째로 집어넣기
저의 첫 번째 본능은 다음과 같았습니다: 전체 스펙 YAML 파일을 채팅창에 붙여넣고 "테스트를 작성해줘"라고 말하는 것이었습니다.
결과: 보기에는 아주 훌륭한 테스트들을 생성했습니다. fixture가 포함된 pytest, 매개변수화된 입력 (parameterized inputs), 응답 검증 (response validation) 등 모든 것이 갖춰져 있었습니다. 하지만 단 하나도 통과하지 못했습니다.
문제는 미묘했습니다. AI가 존재하지 않는 응답 필드 (response fields)를 만들어냈습니다. 저의 /users/{id}는 {"id", "email", "created_at"}를 반환합니다. 하지만 AI가 생성한 테스트는 해당 엔드포인트가 절대 반환하지 않는 필드인 response.json()["name"]을 단언 (assert)했습니다.
교훈: LLM (Large Language Models)은 API 구조를 환각 (hallucinate)합니다. 생성된 테스트를 실행하기 전에 항상 실제 스키마 (schema)와 대조하여 검증하십시오.
시도 2: 도구 증강 생성 (Tool-Augmented Generation)
두 번째 시도: AI에게 구조화된 컨텍스트 (context)를 제공하는 작은 Python 스크립트를 작성했습니다:
import json
# 모델이 오해할 수 없도록 스키마를 평탄한 구조로 추출
...
이 방법은 훨씬 더 효과적이었습니다. AI에게 가공되지 않은 스펙 페이지 대신 _계산된 요약 (computed summary)_을 제공함으로써, 환각 (hallucination) 발생률이 극적으로 감소했습니다. 테스트가 첫 실행에서 통과하는 비율이 약 70%까지 올라갔습니다.
시도 3: "리뷰 루프 (Review Loop)"
70%의 통과율(pass rate)도 개선된 결과지만, 나머지 30%는 여전히 수동으로 수정해야 했습니다. 그래서 피드백 루프(feedback loop)를 추가했습니다.
# 1. 테스트 생성
ai-cli generate-tests --spec openapi.json > test_api_v2.py
...
이를 통해 두 번째 반복(iteration)에서는 통과율이 약 95%까지 올라갔습니다. 남은 5%는 명백히 모호한 사례들이었습니다. 즉, 명세(spec)가 동작을 완전히 설명하지 못하는 엔드포인트(예: 속도 제한(rate limit) 응답이나 조건부 필드 등)였습니다.
핵심 통찰(Key insight): 한 번에 완벽한 테스트를 생성하려고 하지 마세요. 완벽한 프롬프팅(prompting)을 한 번 시도하는 것보다, 실제 에러 피드백을 반영하여 두 번 실행하는 것이 훨씬 효과적입니다.
실제로 효과가 있었던 것 (최종적으로 결정한 스택)
한 달간의 반복 과정을 거쳐, 제가 최종적으로 정착한 구성은 다음과 같습니다.
┌─────────────────┐ ┌──────────────────┐
│ OpenAPI 명세 │────▶│ 스키마 추출기 │
│ (openapi.json) │ │ (Python 스크립트) │
...
그리고 가장 큰 차이를 만들어낸 프롬프트 템플릿(prompt template)은 다음과 같습니다.
당신은 API 테스트 전문가입니다. 다음 엔드포인트 스키마(endpoint schemas)가 주어지면,
pytest 테스트 스위트(test suite)를 생성하세요.
...
마지막 규칙인 '임포트(import)'에 관한 규칙은 그 어떤 것보다 많은 시간을 절약해 주었습니다. 이전 버전들은 제가 설치하지도 않은 무작위 라이브러리들을 임포트하곤 했습니다.
수치
| 지표 | 수동 (Manual) | AI 지원 (AI-Assisted) |
|---|---|---|
| 테스트 스위트 작성 시간 (40개 엔드포인트) | 약 4시간 | 약 45분 |
| ... |
시간 절약 효과는 확실합니다. 하지만 이는 인간의 검토를 없애서가 아니라, _초안(first draft)_을 작성하는 속도에서 오는 것입니다. 저는 여전히 생성된 모든 테스트를 검토합니다. 다만 더 이상 빈 파일에서 시작하지 않을 뿐입니다.
효과가 없었던 것
- 완전 자율 모드 (Fully autonomous mode). "설정해두고 잊어버리기 (set it and forget it)"를 시도할 때마다 CI(지속적 통합) 상에서는 괜찮아 보이지만 실제 버그는 놓치는 테스트 스위트가 생성되었습니다. AI는 여러분의 비즈니스 로직 (Business logic)을 알지 못합니다.
- 컨텍스트 없는 테스트 데이터 생성. AI가 생성한 테스트 데이터(이름, 이메일, ID 등)는 종종 데이터베이스 제약 조건 (Database constraints)을 위반했습니다. 결국 이를 위해 Faker를 사용한 팩토리 (Factories)를 사용하게 되었습니다.
- 복잡한 어설션 체인 (Complex assertion chains). AI에게 다단계 워크플로(사용자 생성 → 사용자 업데이트 → 업데이트 확인 → 사용자 삭제 → 삭제 확인)를 작성하도록 요청했습니다. 모델들은 단계 간의 상태 (State)에 대해 혼란을 겪었습니다. 이러한 워크플로는 독립적인 테스트로 나누는 것이 더 낫습니다.
결론 (Bottom Line)
AI가 API 테스터를 대체하지는 않겠지만, 지루한 부분들을 처리하는 데 있어 놀라운 가속기 역할을 할 것입니다. 저에게 효과적이었던 워크플로는 다음과 같습니다:
- 구조화된 컨텍스트 추출: 스펙 (Spec)에서 구조화된 컨텍스트를 추출하세요. 가공되지 않은 YAML을 그대로 던져주지 마세요.
- 루프를 통한 생성 + 실행 + 수정: 한 번에 완벽함을 기대하지 말고, 생성하고 실행하고 수정하는 루프를 반복하세요.
- 항상 검토: AI가 작성한 내용을 항상 검토하세요.
- 엄격한 제약 조건 부여: 어떤 라이브러리를 사용할지, 어떤 패턴을 따를지 명확히 지정하세요.
이제 저는 테스트 보일러플레이트 (Boilerplate)에 쓰는 시간을 줄이고, 무엇을 테스트할지 고민하는 데 더 많은 시간을 쓰고 있습니다. 이것이 진정한 승리입니다.
AI와 테스트에 대한 여러분의 경험은 어떠신가요? 더 효과적인 접근 방식을 찾으셨나요? 댓글로 알려주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기