API를 수동으로 테스트하는 것을 멈추세요. AI 에이전트에게 Bruno 워크플로를 부여하세요.
요약
API 테스트 워크플로를 코드와 함께 관리하여 AI 에이전트의 활용도를 높이는 방법을 제안합니다. 오픈 소스 API 클라이언트인 Bruno를 사용하여 API 컬렉션을 Git 리포지토리에 텍스트 파일로 저장함으로써, 에이전트가 명확한 워크플로를 파악할 수 있도록 합니다.
핵심 포인트
- API 컬렉션을 코드 근처(Git 리포지토리)에 배치하여 워크플로 패키징 문제 해결
- Bruno를 활용해 API 요청을 실행 가능한 리포지토리 산출물로 관리
- AI 에이전트가 암묵적 지식 없이도 복잡한 API 흐름을 이해하고 테스트할 수 있는 환경 구축
- CI/CD 및 팀 협업 시 일관된 API 테스트 환경 제공
대부분의 API 테스트 워크플로 (workflow)는 지루한 방식으로 망가집니다.
팀이 테스트를 신경 쓰지 않기 때문이 아닙니다.
아무도 요청 (request)을 보내는 방법을 모르기 때문도 아닙니다.
API 워크플로가 너무 많은 곳에 동시에 존재하기 때문입니다.
한 개발자는 Postman 컬렉션 (collection)을 가지고 있습니다.
다른 개발자는 셸 히스토리 (shell history)에 몇 개의 curl 명령어를 가지고 있습니다.
백엔드 리포지토리 (backend repo)에는 .env.example에 환경 변수 (environment variables)가 있습니다.
CI에는 단 하나의 엔드포인트 (endpoint)만 확인하는 스모크 테스트 (smoke test)가 있습니다.
문서 (docs)는 한 가지를 말합니다.
스테이징 (staging) API는 약간 다르게 동작합니다.
그때 AI 코딩 에이전트 (AI coding agent)가 리포지토리에 들어와 다음과 같은 질문을 받습니다:
이 API 흐름 (flow)을 확인해 줄 수 있어?
에이전트는 코드를 읽을 수 있습니다.
테스트를 작성할 수 있습니다.
curl 명령어를 생성할 수 있습니다.
HTTP 상태 코드 (status codes)를 설명할 수 있습니다.
하지만 에이전트도 신입 개발자가 겪는 것과 똑같은 문제를 겪습니다.
API 워크플로는 어디에 있는가?
만약 답이 "GUI 도구 어딘가, 누군가의 로컬 히스토리, 그리고 여기저기 흩어진 문서들"이라면, 에이전트는 모든 것을 처음부터 다시 재구성해야 합니다.
이것은 도구의 문제가 아닙니다.
이것은 워크플로 패키징 (workflow packaging)의 문제입니다.
API 컬렉션은 코드 근처에 있어야 합니다
이것이 제가 Bruno를 좋아하는 이유입니다.
Bruno는 컬렉션을 Git 리포지토리 (Git repository) 내의 일반 텍스트 파일로 저장하는 오픈 소스 (open-source) API 클라이언트 (client)입니다.
이 세부 사항은 UI보다 더 중요합니다.
API 컬렉션이 애플리케이션 코드 옆에 있으면, 그것은 엔지니어링 시스템 (engineering system)의 일부가 됩니다:
- 요청 변경 사항이 풀 리퀘스트 (pull requests)에 나타납니다.
- 환경 파일 (environment files)을 검토할 수 있습니다.
- 인증 흐름 (auth flows)을 실행 가능한 요청으로 문서화할 수 있습니다.
- 테스트 어서션 (test assertions)이 필요한 요청과 함께 존재할 수 있습니다.
- CI는 사람이 로컬에서 사용하는 것과 동일한 컬렉션을 실행할 수 있습니다.
- 새로운 팀원들은 컬렉션을 실행함으로써 API를 배울 수 있습니다.
컬렉션은 동기화된 워크스페이스 (workspace)에 숨겨진 개인적인 산출물이 아닙니다.
그것은 리포지토리 산출물 (repo artifact)입니다.
이것은 AI 에이전트가 그것으로 할 수 있는 일을 변화시킵니다.
실제 단위는 요청이 아닙니다
단일 API 요청은 쉽습니다.
유용한 워크플로는 보통 일련의 순서입니다:
- 로그인 (Login).
- 토큰 저장 (Save the token).
- 리소스 생성 (Create a resource).
- 다시 읽기 (Read it back).
- 업데이트 (Update it).
- 응답 형태 검증 (Verify the response shape).
- 정리 또는 실패 경로 테스트 (Clean up or test the failure path).
개발자들이 이를 수동으로 테스트할 때, 종종 머릿속으로 그 순서를 기억합니다.
그것은 API가 변경될 때까지는 작동합니다.
스테이징 (staging) 환경의 데이터가 달라질 때까지는 작동합니다.
다른 누군가가 동일한 흐름을 디버깅해야 할 때까지는 작동합니다.
에이전트 (agent)가 이를 실행해야 하고 암묵적 지식 (tribal memory)에 의존할 수 없게 될 때까지는 작동합니다.
인코딩 (encode)해야 할 중요한 것은 다음과 같은 것이 아닙니다:
POST 요청을 보냅니다.
그것은 다음과 같습니다:
이것은 인증 흐름 (auth flow)입니다.
이 변수들은 한 요청에서 다음 요청으로 이동합니다.
이 어설션 (assertions)들은 계약 (contract)이 여전히 작동함을 증명합니다.
...
이 지점에서 Bruno의 파일 기반 모델 (file-based model)이 유용해집니다.
.bru 요청은 요청 메타데이터 (metadata), 헤더 (headers), 바디 (body), 스크립트 (scripts), 그리고 테스트 (tests)를 사람이 읽을 수 있는 형식으로 포함할 수 있습니다.
환경 파일 (environment file)은 baseUrl, 테스트 사용자, 그리고 비밀 플레이스홀더 (secret placeholders)를 정의할 수 있습니다.
응답 후 스크립트 (Post-response scripts)는 이후의 요청을 위해 값을 저장할 수 있습니다.
CLI는 컬렉션 (collection)을 실행할 수 있습니다:
bru run --env staging
또는 폴더를 실행할 수 있습니다:
bru run auth/ --env dev
또는 CI 친화적인 결과를 출력할 수 있습니다:
bru run --env dev --output results.xml --format junit
이것은 에이전트에게 "API를 테스트하세요."와 같은 모호한 지시보다 훨씬 더 나은 아티팩트 (artifact)입니다.
AI 에이전트가 즉흥적으로 해서는 안 되는 것
저는 에이전트가 매번 API 테스트 워크플로 (workflow)를 스스로 만들어내는 것을 원하지 않습니다.
그것이 바로 인상적으로 보이는 활동은 만들지만 검증은 취약하게 만드는 방식입니다.
에이전트는 다음과 같은 행동을 할 수 있습니다:
- 해피 패스 (happy path)만 실행함
- 잘못된 환경 (environment)을 대상으로 테스트함
- 인증 상태 (auth state)를 잊어버림
- 실제 버그를 우회하는 가짜 데이터를 사용함
- 어설션 (assertions)을 건너뛰고 요청이 무언가를 반환했다는 사실만 보고함
- 아무도 다시 실행하지 않을 curl 명령어를 붙여넣음
이러한 실패 중 어느 것도 극적으로 보이지 않습니다.
그것들은 마치 일을 한 것처럼 보입니다.
에이전트는 다음과 같이 말합니다:
엔드포인트 (endpoint)를 테스트했습니다.
하지만 팀에는 지속 가능한 아티팩트 (durable artifact)도, 디프 (diff)도, 재사용 가능한 흐름 (reusable flow)도, CI 훅 (CI hook)도 없습니다.
그것은 잘못된 최종 상태입니다.
API 작업을 위해, 저는 에이전트가 저장소 (repo)에 남길 수 있는 무언가를 남기기를 원합니다.
에이전트를 위한 더 나은 Bruno 워크플로 (workflow)
제가 AI 코딩 에이전트에게 바라는 워크플로 (workflow)는 다음과 같습니다.
1. API 표면 (API surface) 탐색
에이전트는 라우트 (routes), 컨트롤러 (controllers), 존재하는 경우 OpenAPI 명세 (specs), 기존 테스트, 그리고 현재의 모든 API 문서 (docs)를 조사해야 합니다.
출력물은 다음과 같은 짧은 지도 형태여야 합니다:
- 인증 엔드포인트 (auth endpoints)
- 핵심 리소스 (core resources)
- 파괴적인 작업 (destructive actions)
- 환경 가정 (environment assumptions)
- 테스트 데이터 요구사항 (test data requirements)
- 체이닝된 상태 (chained state)가 필요한 흐름 (flows)
아직 컬렉션 (collection) 변경은 하지 않습니다.
먼저 형태를 이해하십시오.
2. Git 친화적인 컬렉션 구조 생성
컬렉션 (collection)은 에이전트의 사고 과정이 아니라 API를 반영해야 합니다.
예를 들어:
api-collection/
bruno.json
environments/
...
이러한 구조는 의도적으로 지루하게 설계되었습니다.
사람들이 탐색할 수 있습니다.
에이전트가 탐색할 수 있습니다.
검토자 (reviewers)가 차이 (diff)를 확인할 수 있습니다.
3. 변수와 비밀 값 (secrets)을 올바르게 인코딩
환경 파일 (environment files)은 다음과 같은 일반적인 설정 (config)을 포함해야 합니다:
baseUrl: http://localhost:3000
testEmail: test@example.com
비밀 값 (secrets)은 비밀 값으로 표시되어야 하며, 평문 값으로 커밋되어서는 안 됩니다.
이것은 에이전트에게 '느낌 (vibes)'이 아닌 '규칙 (rule)'이 필요한 부분 중 하나입니다.
도구가 요청 (requests)을 실행할 수 있다면, 실수로 자격 증명 (credentials)을 유출할 수도 있습니다.
따라서 워크플로 (workflow)는 설정 (config)이 어디에 위치하는지, 어떤 값이 커밋될 수 있는지, 그리고 무엇이 로컬에 머물거나 CI에 의해 주입되어야 하는지를 정의해야 합니다.
4. 의도적으로 요청 체이닝 (chain requests)
많은 실제 API 테스트는 상태 유지 (stateful) 방식입니다.
로그인 (Login)은 토큰 (token)을 반환합니다.
사용자 생성 (Create user)은 ID를 반환합니다.
주문 생성 (Create order)은 사용자에 의존합니다.
환불 (Refund)은 주문에 의존합니다.
에이전트는 실제 응답 (response)에서 해당 ID들을 캡처할 수 있음에도 불구하고 이를 가짜로 만들어서는 안 됩니다.
이 지점에서 응답 후 스크립트 (post-response scripts)가 유용합니다.
핵심은 영리한 스크립팅 (scripting)이 아닙니다.
핵심은 API 흐름 (flow)을 설명적인 것이 아니라 실행 가능한 것으로 만드는 것입니다.
5. 요청 옆에 단언 (assertions) 배치
단언 (assertions)이 없는 요청은 단순한 연기 신호 (smoke signal)에 불과합니다.
에이전트는 중요한 계약 (contract)에 대한 테스트를 추가해야 합니다:
- 상태 코드 (status code)
- 필수 필드 (required fields)
- 예상 타입 (expected types)
- 인증 동작 (auth behavior)
- 에러 구조 (error shape)
- 권한 경계 (permission boundaries)
- 관련 시의멱등성 또는 재시도 동작 (idempotency or retry behavior when relevant)
테스트는 다음 질문에 답해야 합니다:
What would make this endpoint unsafe to ship?
다음과 같아서는 안 됩니다:
Did the server return any JSON?
6. CI 명령 추가 (Add a CI command)
워크플로우는 팀이 다시 실행할 수 있는 명령어가 있을 때까지 완료되지 않습니다.
예를 들어:
bru run --env staging
또는:
bru run auth/ users/ --env ci --output results.xml --format junit
정확한 명령어는 프로젝트에 따라 다릅니다.
하지만 아티팩트(artifact)는 개발자, CI 작업, 또는 미래의 에이전트가 동일한 검사를 반복할 수 있을 만큼 명확해야 합니다.
Terminal Skills에서 적합한 이유 (Where Terminal Skills fits)
이것은 스킬(skill)에 속해야 하는 바로 그 종류의 워크플로우입니다.
Terminal Skills 카탈로그에는 AI 에이전트를 위한 bruno 스킬이 있습니다:
유용한 부분은
에이전트는 엔드포인트(endpoint)에 대한 설득력 있는 설명을 생성할 수 있습니다.
샘플 요청(sample requests)을 생성할 수도 있습니다.
테스트가 통과되었다고 말할 수도 있습니다.
하지만 워크플로(workflow)가 지속적인 아티팩트(artifact)를 남기지 않는다면, 그 가치는 채팅이 끝난 후 사라져 버립니다.
더 나은 결과는 다음과 같습니다:
- Bruno 컬렉션(collection)이 업데이트됨
- 변경 사항이 Git에 표시됨
- 요청에 어설션(assertions)이 포함됨
- 환경(environment)이 명시적임
- 명령어를 로컬에서 실행할 수 있음
- 나중에 CI(지속적 통합)에서 실행할 수 있음
- 다음 에이전트가 워크플로를 다시 찾아낼 필요가 없음
이것이 단순한 보조(assistance)와 운영 메모리(operational memory)의 차이입니다.
에이전트는 단순히 API를 테스트한 것이 아닙니다.
팀이 API를 테스트하는 방식을 개선한 것입니다.
나의 실무 체크리스트
만약 제가 에이전트가 생성한 Bruno 워크플로를 검토한다면, 다음과 같은 질문을 던질 것입니다:
- 컬렉션이 리포지토리(repo)에 저장되어 있는가?
- 폴더 구조가 API 형태와 일치하는가?
- 환경(environments)이 깔끔하게 분리되어 있는가?
- 비밀값(secrets)이 표시되어 있고 커밋되는 값에서 제외되었는가?
- 중요한 요청에 어설션(assertions)이 포함되어 있는가?
- 인증 토큰(auth tokens)과 ID가 실제 응답 상태(response state)를 통해 전달되는가?
- 컬렉션을 CLI(명령줄 인터페이스)에서 실행할 수 있는가?
- CI 준비가 된 명령어가 있는가?
- 새로운 팀원이 이를 읽고 실행한 후 API를 더 빠르게 이해할 수 있는가?
대답이 '예'라면, 에이전트는 유용한 무언가를 남긴 것입니다.
대답이 '아니오'라면, 그것은 아마도 단순히 추가 단계만 더해진 수동 테스트에 불과할 것입니다.
더 넓은 교훈
AI 에이전트는 일회성 작업을 수행하는 데 능숙합니다.
엔지니어링 팀에는 반복 가능한 작업이 필요합니다.
그것이 바로 스킬(skills)이 메워야 할 간극입니다.
API 테스트의 경우, 그 차이가 특히 눈에 띄게 나타납니다.
에이전트가 요청을 딱 한 번 보내기를 원하십니까?
아니면 팀이 계속 사용할 수 있는 API 워크플로를 구축하기를 원하십니까?
이것이 Bruno가 Terminal Skills에 적합한 이유입니다.
Bruno는 API 테스트를 파일, 디프(diffs), 명령어, 그리고 체크(checks)로 변환합니다.
그리고 이것들은 바로 에이전트가 모든 사람에게 채팅 기록을 신뢰하라고 요구하지 않고도 사용할 수 있는 종류의 아티팩트(artifacts)입니다.
고지: 이 기사의 초안 작성 및 편집에는 AI 보조가 사용되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기