Apidog CLI를 활용한 데이터 기반 API 테스트: CSV 및 JSON 반복

Apidog CLI -d 플래그 실습 가이드: CSV, JSON 또는 저장된 데이터 세트에서 테스트 시나리오를 구동하고, 바인딩을 디버깅하며, CI에서 데이터 기반 테스트를 실행합니다.

INEZA Felin-Michel

INEZA Felin-Michel

16 June 2026

Apidog CLI를 활용한 데이터 기반 API 테스트: CSV 및 JSON 반복

Apidog 엔터프라이즈

온프레미스 배포

SSO & RBAC

SOC 2 준수

Apidog Enterprise 살펴보기

결제 엔드포인트에 대한 견고한 테스트 시나리오를 구축했습니다. 이 시나리오는 세 가지 요청을 연결하고, 각 응답을 어설션하며, 실행을 클릭할 때마다 통과합니다. 하지만 파이프라인에서는 마흔 가지 입력 조합을 커버하고, QA 리더가 관리하는 파일에서 데이터를 가져오며, 다른 자격 증명으로 스테이징 및 프로덕션 환경에서 동일한 시나리오를 실행해야 합니다. 노트북에서 작동했던 포인트 앤 클릭 방식으로는 이를 구현할 수 없으며, 시나리오를 마흔 번 복제하고 싶지도 않을 것입니다.

이 마지막 단계는 명령줄이 처리합니다. Apidog를 사용하면 시각적 빌더에서 테스트 시나리오를 한 번 작성한 다음, apidog-cli 패키지를 통해 터미널에서 실행할 수 있습니다. 하나의 시나리오를 데이터 기반 실행으로 전환하는 플래그는 --iteration-data의 약자인 -d입니다. 이 플래그는 CSV 파일, JSON 파일 또는 Apidog 프로젝트에 저장된 데이터 세트를 받아 각 행의 값을 요청이 참조하는 변수에 바인딩하여 시나리오를 행당 한 번씩 실행합니다.

button

-d 플래그가 파일을 읽는 방법

전체 기능은 하나의 옵션에 담겨 있습니다. 다음은 apidog run --help에서 바로 가져온 긴 형식과 짧은 형식입니다.

-d, --iteration-data <path|testDataId>   Define the data which use for iterations (either JSON or CSV)

<path|testDataId>는 대부분의 사람들이 놓치는 세부 사항입니다. 이 인수는 오버로드되어 있습니다. 경로를 전달하면 CLI가 디스크에서 로컬 파일을 읽습니다. 테스트 데이터 ID를 전달하면 CLI가 Apidog 프로젝트 내에 저장한 데이터 세트를 가져옵니다. 동일한 플래그이지만 두 가지 소스를 사용하며, 실행기는 어떤 것을 전달했는지 파악합니다.

로컬 파일 형식은 일반적인 시작점입니다. 명령을 실행하는 위치를 기준으로 파일을 지정합니다.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv -r cli

CLI는 checkout-cases.csv 파일을 열고 헤더 아래의 행 수를 센 다음, 시나리오 605067을 행당 한 번씩 실행합니다. 각 실행에서 열을 요청의 일치하는 변수에 바인딩하고, 시나리오를 실행하며, 해당 반복의 결과를 기록합니다. 마흔 개의 행, 마흔 번의 실행, 하나의 시나리오입니다.

형식은 파일을 따릅니다. 동일한 플래그는 추가 옵션 없이 JSON을 허용합니다.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.json -r cli

CLI에 어떤 형식을 사용하는지 알려줄 필요가 없습니다. CLI는 확장자와 파일 모양을 읽습니다. 즉, 열 이름과 JSON 키가 시나리오가 예상하는 변수와 일치하는 한, 명령을 건드리지 않고 프로젝트 중간에 CSV를 JSON 배열로 교체할 수 있습니다.

CLI가 각 파일 내에서 예상하는 것

CSV는 평면적이고 표 형식의 경우를 위한 형식입니다. 헤더 행은 변수 이름을 지정합니다. 그 아래의 모든 행은 하나의 반복입니다. 다음은 할인 엔드포인트에 대한 실제 checkout-cases.csv 파일입니다.

sku,quantity,coupon,expected_status,expected_total
DESK-01,1,SAVE10,200,89.10
DESK-01,0,SAVE10,422,0
CHAIR-09,3,,200,447.00
DESK-01,1,EXPIRED,410,0
GHOST-99,1,SAVE10,404,0

다섯 개의 열은 다섯 개의 변수가 됩니다. 요청 본문에는 {{sku}}{{quantity}}를 작성하고, 어설션에서는 응답을 {{expected_status}}{{expected_total}}과 비교합니다. 실행기는 행당 이들을 바인딩합니다. 세 번째 행의 빈 coupon 셀은 빈 문자열이 되며, 이는 커버하려는 쿠폰 없음 사례와 정확히 일치합니다.

JSON은 케이스에 중첩된 구조가 있어 열로 제대로 평면화되지 않을 때 사용되는 형식입니다. 파일은 객체 배열이며, 각 반복당 하나의 객체입니다.

[
  {
    "label": "valid order, two items",
    "order": {
      "items": [
        { "sku": "DESK-01", "qty": 1 },
        { "sku": "CHAIR-09", "qty": 2 }
      ],
      "shipping": { "country": "US", "method": "ground" }
    },
    "expected_status": 200
  },
  {
    "label": "unshippable country",
    "order": {
      "items": [{ "sku": "DESK-01", "qty": 1 }],
      "shipping": { "country": "ZZ", "method": "ground" }
    },
    "expected_status": 422
  }
]

시나리오 내에서 {{order}}{{expected_status}}를 동일한 방식으로 참조하면 실행기는 각 객체의 필드를 반복에 전달합니다. label 필드는 사용자를 위한 것입니다. 이 필드는 보고서에 표시되어 실패한 테스트가 "iteration 2" 대신 "unshippable country"로 읽히게 하여, 5초 진단과 5분 진단의 차이를 만듭니다.

몇 가지 규칙을 통해 CI에서 이러한 파일로 인한 문제를 방지할 수 있습니다.

이러한 바인딩된 값을 읽는 어설션을 작성하는 JSONPath 측면에 대해서는 JSON 응답에서 어설션 설정 및 변수 추출 문서에서 구문을 자세히 설명합니다.

파일 대신 저장된 데이터 세트에서 실행하기

-d의 두 번째 형식은 대부분의 설명서에 나타나지 않는 것입니다. 경로 대신 테스트 데이터 ID를 전달합니다.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d 38291 -r cli

이제 CLI는 실행기 디스크에서 파일을 읽는 대신 Apidog 프로젝트에서 해당 ID를 가진 데이터 세트를 가져옵니다. 이는 데이터가 레포가 아닌 팀과 함께 있을 때 유용합니다. QA 리더가 Apidog 내에서 케이스 테이블을 유지 관리하고 앱에서 편집하면, 모든 CI 실행은 아무도 CSV를 커밋하지 않고도 현재 버전을 가져옵니다. 시나리오, 환경, 데이터는 모두 서버 측에 있으며, 명령은 ID로 이름을 지정하기만 합니다.

트레이드오프는 진실의 원천이 어디에 있느냐입니다. 커밋된 CSV는 풀 리퀘스트에서 diff를 비교할 수 있고 테스트 중인 커밋에 고정된 데이터 세트를 제공합니다. 저장된 테스트 데이터 ID는 모든 사람이 한 곳에서 편집하는 단일 공유 테이블을 제공합니다. 둘 다 틀린 것은 아닙니다. 데이터가 코드와 함께 동기화되어야 할 때는 커밋된 파일을 선택하고, 데이터가 레포를 건드리지 않는 사람들이 소유할 때는 저장된 ID를 선택하세요.

내보낸 파일에서 오프라인으로 실행하기

CLI에 데이터를 공급하는 세 번째 방법이 있으며, 이는 전체 명령의 형태를 바꿉니다. Apidog에서 테스트 케이스를 자체 포함 파일로 내보내어 해당 파일을 시나리오 ID나 시나리오를 가져오기 위한 네트워크 왕복 없이 직접 실행할 수 있습니다.

apidog run ./checkout.apidog-cli.json -r cli,html

여기서 첫 번째 인수는 플래그가 아니라 내보낸 테스트 케이스 자체인 file-source입니다. CLI는 파일에 있는 내용을 실행합니다. 여전히 -d를 사용하여 반복 데이터를 추가합니다.

apidog run ./checkout.apidog-cli.json -d ./checkout-cases.csv -r cli,junit

이는 두 가지 상황에서 중요합니다. 첫째는 시나리오 ID를 해결하기 위해 Apidog 클라우드에 도달할 수 없는 에어갭 또는 잠긴 CI 실행기입니다. 내보낸 파일은 실행에 필요한 모든 것을 포함합니다. 둘째는 재현성입니다. 내보낸 파일은 내보내기 시점의 시나리오의 고정된 스냅샷이므로, 나중에 앱에서 시나리오를 편집해도 실행에 영향을 주지 않습니다. 이 설치 및 첫 실행 메커니즘에 대해서는 Apidog CLI 설치 가이드에서 바이너리 설치를 다루고, Apidog CLI 전체 참조에서는 모든 플래그를 한 표에 문서화합니다.

-d-n 및 변수 오버라이드 연결하기

데이터 기반 실행은 거의 단독으로 실행되지 않습니다. 세 가지 플래그가 -d와 계속해서 연결됩니다.

-n, --iteration-count은 시나리오가 실행되는 횟수를 설정합니다. 데이터 파일을 제공할 때, 행 수가 이미 반복을 결정하므로 일반적으로 -n을 생략하고 파일이 결정하도록 합니다. -n은 주로 테이블을 한 번 이상 실행하고 싶을 때, 또는 고정된 시나리오를 반복하는 soak 테스트와 같이 데이터 파일 없이 실행할 때 사용합니다.

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -n 50 -r cli

--env-var--global-var는 프로젝트 환경을 건드리지 않고 런타임에 key=value 쌍을 주입합니다. 이는 시나리오와 데이터 파일 모두에서 시크릿 및 파이프라인별 구성을 제외하는 방법입니다. 데이터 파일은 테스트 케이스를 포함하고, 오버라이드는 실행마다 변경되는 항목을 포함합니다.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  --env-var "base_url=https://staging.internal" \
  --global-var "api_key=$RUNTIME_API_KEY" \
  -r cli,junit

이 분리는 의도적입니다. 반복 데이터는 모든 곳에서 동일하게 실행되는 부분, 즉 엔드포인트가 처리해야 하는 케이스입니다. 변수 오버라이드는 환경마다 변경되는 부분, 즉 호스트, 키, 테넌트입니다. 자격 증명은 CI 시크릿 스토어에 보관하고, 위에 $RUNTIME_API_KEY처럼 환경 변수에서 --global-var를 통해 전달하세요. 레포 접근 권한이 있는 누구라도 읽을 수 있는 CSV에 자격 증명을 절대 포함하지 마세요.

반복별 결과 읽기

데이터 기반 실행은 어떤 행이 실패했는지 알 수 있을 때만 유용합니다. 리포터 플래그가 반환되는 내용을 결정합니다.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  -r cli,junit --out-dir ./test-reports

-r cli는 빌드 로그에서 스캔하는 읽기 가능한 반복별 분석을 터미널에 출력합니다. -r junit은 JUnit XML을 작성하며, 이는 거의 모든 CI 대시보드가 통과/실패 트리로 파싱하는 형식으로, 실패한 행이 숨겨진 로그 텍스트 대신 명명된 실패 테스트로 표시됩니다. htmljson도 전달할 수 있습니다. html은 빌드 아티팩트로 보관할 수 있는 탐색 가능한 보고서를 제공하고, json은 결과를 후처리할 경우 원시 구조화된 출력을 제공합니다. --out-dir는 파일을 보관할 수 있도록 파일이 저장될 위치를 제어합니다.

기본적으로 실행은 첫 번째 실패 어설션에서 중지됩니다. 넓은 데이터 테이블의 경우 일반적으로 잘못된 호출입니다. 왜냐하면 하나를 고치고 다음을 찾기 위해 다시 실행하는 대신, 한 번의 실행에서 모든 실패 행을 확인하고 싶기 때문입니다. --on-error로 동작을 전환하세요.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  --on-error continue \
  -r cli,junit --out-dir ./test-reports

--on-error continue는 이전 반복이 실패하더라도 모든 반복을 실행하므로, 하나의 보고서에서 두 번째, 일곱 번째, 열아홉 번째 행이 한 번에 깨졌음을 보여줍니다. 실패한 것이 있으면 실행은 여전히 0이 아닌 종료 코드로 끝나므로 실제 게이트 역할을 합니다. --on-error end는 빠른 스모크 테스트를 위한 빠른 실패 기본값이며, ignore는 실행을 방해하고 싶지 않은 드물게 알려진 불안정한 단계를 위한 것입니다.

조용히 아무것도 하지 않는 바인딩 디버깅하기

데이터 기반 실행에서 가장 많은 시간을 낭비하게 하는 실패 모드는 빨간색 어설션이 아닙니다. 데이터가 요청에 바인딩되지 않아 아무것도 테스트하지 않은 초록색 실행입니다. 요청은 빈 값으로 전송되었고, 엔드포인트는 빈 페이로드에 대해 200을 반환했으며, 어설션은 우연히 통과했습니다. 커버리지는 괜찮아 보이지만, 실제로는 그렇지 않습니다.

데이터 기반 실행이 이상하게 작동할 경우, --verbose를 추가하세요.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  --verbose -r cli

--verbose는 각 반복에 대한 전체 요청 및 응답을 출력합니다. 실행기가 실제로 보낸 요청 본문을 확인하세요. {{sku}}가 대체되지 않은 채 있거나, CSV 셀이 비어 있지 않은데도 값이 비어 있다면 바인딩이 깨진 것입니다. 흔히 발생하는 세 가지 원인은 다음과 같습니다(발생 빈도 순).

일반적인 규칙: 반복이 통과했지만 통과해서는 안 된다고 의심될 때는, 녹색 결과를 신뢰하기 전에 상세한 요청 하나를 읽어보세요. 빈 입력에 대해 실행되는 테스트는 아무 테스트도 없는 것보다 나쁩니다. 왜냐하면 엔드포인트가 테스트되지 않는 동안 모든 것이 괜찮다고 알려주기 때문입니다.

CI에 연결하기

이점은 누구도 실행을 클릭하지 않고도 모든 변경 사항에 대해 전체 테이블이 실행된다는 것입니다. 다음은 CLI를 설치하고 각 풀 리퀘스트에 대해 CSV 기반 시나리오를 실행하는 GitHub Actions 작업입니다.

name: Data-driven API tests
on: [pull_request]

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install Apidog CLI
        run: npm install -g apidog-cli
      - name: Run data-driven scenario
        env:
          APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
        run: |
          apidog run --access-token $APIDOG_ACCESS_TOKEN \
            -t 605067 -e 1629989 \
            -d ./test-data/checkout-cases.csv \
            --on-error continue \
            -r cli,junit --out-dir ./test-reports
      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: api-test-report
          path: ./test-reports

토큰은 레포 설정에서 한 번 설정되는 secrets.APIDOG_ACCESS_TOKEN에서 가져옵니다. --on-error continue는 첫 번째 실패에서 멈추는 대신 모든 실패 행을 하나의 보고서에 수집합니다. 업로드의 if: always()는 실행이 실패하더라도 보고서를 유지하며, 이때 가장 보고서를 읽고 싶을 때입니다. CSV 경로를 JSON 파일 또는 저장된 테스트 데이터 ID로 바꾸어도 다른 것은 변경되지 않습니다.

동일한 세 가지 단계는 모든 CI 시스템에 적용됩니다. Node.js와 CLI를 설치하고, 토큰을 환경 변수로 노출하며, -d와 함께 apidog run을 호출합니다. GitLab CI, Jenkins, CircleCI 등은 플랫폼별 테스트 재작성이 필요 없습니다. Actions 측면에 대한 더 자세한 설명은 GitHub Actions에서 API 테스트 자동화하기를 참조하고, 리포터, 오류 처리 및 TLS를 포함한 CLI의 전체 플래그 표면은 완벽한 Apidog CLI 가이드에서 모든 옵션을 설명합니다.

테스트를 확장하지 않고 확장하는 워크플로

하나의 시나리오와 세 개의 행으로 시작하세요. 요청에 변수 참조를 포함하고 어설션에 예상 결과를 포함하여 앱에서 시나리오를 구축하세요. 정상 경로, 알려진 실패, 그리고 하나의 경계 케이스를 포함하는 CSV를 작성하세요. 세 가지 반복이 모두 제대로 작동할 때까지 -d로 로컬에서 실행하세요.

그런 다음 시나리오가 아닌 데이터를 늘리세요. 모든 버그 보고서는 올바른 예상 출력을 가진 새로운 행이 됩니다. 버그는 영구적인 회귀 테스트 케이스가 되고, 새로운 테스트를 작성할 필요 없이 파일에 한 줄을 추가하는 것으로 끝납니다. 몇 달 동안 이 파일은 프로덕션에서 엔드포인트가 직면하는 실제 문제들을 수집합니다.

마지막으로, --on-error continuejunit 리포터와 함께 apidog run -d 명령을 CI에 추가하세요. 이제 만료된 쿠폰 행을 깨뜨리는 변경 사항은 푸시되는 즉시 빌드를 실패시키고, 깨진 케이스를 직접 가리키는 명명된 반복을 표시합니다. 테이블이 아무리 넓어져도 시나리오는 작고 읽기 쉬운 상태를 유지합니다. 이것이 복합적인 이점입니다. 데이터 입력만으로 커버리지가 증가하고, 유지보수 비용은 그대로 유지됩니다.

이러한 CLI 실행기가 코드 우선 프레임워크와 비교하여 스택에 적합한지 여전히 고민 중이라면, CSV 또는 JSON으로 데이터 기반 API 테스트를 위한 도구 선택 문서에서 접근 방식들을 비교하고, Apidog CLI 대 Newman에서는 Postman 세계의 가장 유사한 명령줄 아날로그를 다룹니다.

자주 묻는 질문

-d는 파일 경로와 저장된 데이터 세트를 모두 받을 수 있나요? -d 플래그는 실행당 하나만 허용합니다: 로컬 CSV 또는 JSON 경로, 또는 Apidog 프로젝트에 저장된 데이터 세트를 가리키는 테스트 데이터 ID. 하나의 값을 전달합니다. 데이터가 레포와 함께 버전 관리되어야 할 때는 파일 경로를 사용하고, 공유 테이블이 앱에 있고 사본을 커밋하고 싶지 않을 때는 저장된 ID를 사용하세요.

CLI에 파일이 CSV인지 JSON인지 알려줘야 하나요? 아닙니다. 실행기는 파일 자체에서 형식을 읽으므로 동일한 -d 플래그가 둘 다 처리합니다. 열 이름(CSV) 또는 객체 키(JSON)를 시나리오가 참조하는 변수 이름과 일치시키면 명령을 변경하지 않고도 형식을 전환할 수 있습니다.

-d-n을 함께 사용하면 어떻게 되나요? 데이터 파일의 행 수가 반복 횟수를 결정하므로, -d와 함께 -n은 일반적으로 필요하지 않습니다. -n은 데이터 파일 없이 실행을 반복하고 싶을 때(예: soak 테스트) 또는 전체 테이블을 한 번 이상 실행하고 싶을 때 사용하세요.

데이터 기반 실행이 아무것도 테스트하지 않고 통과한 이유는 무엇인가요? 가장 흔한 원인은 발생하지 않은 바인딩입니다. 즉, 변수 이름과 일치하지 않는 열 이름이거나, 아무것도 읽지 않는 CI의 잘못된 파일 경로입니다. --verbose를 사용하여 한 번 실행하고 CLI가 보낸 요청 본문을 검사하세요. 대체되지 않은 {{variables}}나 빈 값이 보이면, 녹색 결과를 신뢰하기 전에 이름 불일치나 경로를 수정하세요.

자격 증명을 데이터 파일에서 제외하는 방법은 무엇인가요? 토큰과 키는 CSV나 JSON에서 완전히 제외하세요. --global-var "api_key=$RUNTIME_API_KEY"를 전달하는 것처럼, CI 시크릿 스토어에서 런타임에 --global-var 또는 --env-var를 통해 전달하세요. 데이터 파일은 테스트 입력과 예상 결과만 포함해야 하며, 실행을 인증하는 어떤 것도 포함해서는 안 됩니다.

스테이징 및 프로덕션 환경에 동일한 데이터를 사용할 수 있나요? 네. 시나리오와 데이터 파일은 고정하고 -e로 대상을 전환할 수 있습니다. 동일한 시나리오와 동일한 데이터를 사용하여 풀 리퀘스트 검사를 스테이징 환경 ID로, 배포 후 스모크 테스트를 프로덕션으로 지정할 수 있습니다. 단지 -e 값만 다릅니다. 환경을 데이터와 분리하는 것이 이 방식이 작동하는 이유 전체입니다.

마무리

-d 플래그는 Apidog CLI의 전체 데이터 기반 기능을 나타내며, 처음 보이는 것보다 훨씬 유연합니다. 로컬 CSV 또는 JSON 파일을 읽거나, ID로 프로젝트에 저장된 데이터 세트를 읽습니다. 반복을 위한 -n, 실행별 구성을 위한 --env-var--global-var와 함께 사용되며, 하나의 실행에서 모든 실패 행을 표시하도록 --on-error continue와도 함께 사용됩니다. 온라인 시나리오 ID 또는 오프라인 내보낸 파일에서 실행하고, junitcli 리포터를 통해 반복별 결과를 읽을 수 있습니다.

시나리오를 한 번 만들고, 각 케이스를 행으로 기술하며, 파일에 한 줄이 추가될 때마다 실행기가 커버리지를 확장하도록 하세요. Apidog 다운로드 후, 첫 번째 데이터 파일에 apidog run을 지정하여 단일 시나리오를 모든 푸시마다 실행되는 케이스 테이블로 전환하세요.

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요