GraphQL 엔드포인트를 테스트할 때는 서버가 응답하는지만 확인해서는 부족합니다. user 쿼리가 앱이 사용하는 필드를 실제로 반환하는지, createOrder 뮤테이션이 주문을 저장하는지, 변수 값을 바꿔도 응답 구조가 유지되는지 검증해야 합니다. GraphQL은 보통 단일 URL에 POST 본문으로 쿼리를 전송하므로, 쿼리 문법을 지원하고 스키마 기반 필드 제안과 JSON 응답 어설션을 제공하는 클라이언트가 필요합니다.
Apidog은 HTTP, gRPC, WebSocket, SSE, SOAP와 함께 GraphQL을 전용 요청 유형으로 지원합니다. 이 글에서는 전자상거래 API를 예시로 다음 작업을 단계별로 수행합니다.
- GraphQL 쿼리 작성
- 스키마 가져오기와 코드 완성 활성화
- 변수 전달
- 주문 생성 뮤테이션 실행
- 응답 어설션 추가
- 시나리오와 CLI로 회귀 테스트 자동화
GraphQL의 기본 개념은 공식 GraphQL 문서를 참고하세요. REST와 GraphQL의 선택 기준은 REST 대 GraphQL 비교 글에서 확인할 수 있습니다.
GraphQL 테스트가 REST 테스트와 다른 이유
REST API는 일반적으로 여러 엔드포인트를 제공하며, 각 엔드포인트는 비교적 고정된 응답 구조를 반환합니다.
GET /users/42
반면 GraphQL은 보통 하나의 엔드포인트를 사용하고, 클라이언트가 필요한 필드를 선택합니다.
user(id: 42) {
id
name
orders {
id
status
}
}
테스트 관점에서 차이는 두 가지입니다.
검증 대상은 URL이 아니라 쿼리 문서입니다.
URL과 HTTP 메서드가 맞아도, 필드명·인자·타입이 스키마와 다르면 요청은 실패합니다.HTTP 상태 코드만으로 성공 여부를 판단할 수 없습니다.
GraphQL은 비즈니스 또는 유효성 검사 오류가 있어도 200 OK를 반환할 수 있습니다.
예를 들어 다음 응답은 HTTP 요청 자체는 성공했지만 GraphQL 작업은 실패한 경우입니다.
{
"data": null,
"errors": [
{
"message": "User not found"
}
]
}
따라서 GraphQL 테스트에서는 다음을 함께 검증해야 합니다.
- HTTP 상태 코드
-
errors배열의 존재 여부 -
data내부 필드와 값 - 배열 길이, 타입, 상태값 같은 비즈니스 결과
Apidog에서는 GraphQL 요청 작성, 스키마 기반 자동 완성, 변수, 어설션, 테스트 시나리오를 같은 프로젝트에서 관리할 수 있습니다.
Apidog에서 GraphQL 요청 만들기
먼저 Apidog을 다운로드하거나 브라우저에서 Apidog을 열고 프로젝트를 생성합니다.
1. 새 요청을 만들고 본문을 GraphQL로 설정
-
+버튼을 클릭합니다. -
새 요청을 선택합니다. - HTTP 메서드를
POST로 설정합니다. - GraphQL 엔드포인트를 입력합니다.
https://api.yourstore.com/graphql
- 요청 본문의
Body탭을 엽니다. - 본문 유형으로
GraphQL을 선택합니다.
이제 Query 입력 영역과 변수 입력 영역이 있는 GraphQL 전용 편집기가 표시됩니다.
엔드포인트에 인증이 필요하면 인증 섹션에서 Bearer Token 등을 설정합니다. GraphQL도 내부적으로 HTTP POST 요청이므로 인증 헤더 설정 방식은 일반 HTTP 요청과 동일합니다.
2. 첫 번째 쿼리 작성
Query 입력 영역에 다음 쿼리를 작성합니다.
query GetUserWithOrders {
user(id: "usr_1024") {
id
name
email
orders {
id
total
status
createdAt
}
}
}
이 쿼리는 사용자 한 명과 해당 사용자의 주문 목록을 함께 요청합니다.
실제 API에서 필드 이름은 스키마와 정확히 일치해야 합니다. 예를 들어 서버 스키마가 email 대신 emailAddress를 정의했다면 위 쿼리는 오류를 반환합니다. 다음 단계에서 스키마를 가져오면 이런 실수를 줄일 수 있습니다.
3. 스키마를 가져와 코드 완성 활성화
필드 이름을 문서에서 매번 찾지 않으려면 스키마를 가져옵니다.
- GraphQL 요청 편집기에서
스키마 가져오기를 클릭합니다. - Apidog이 엔드포인트에 인트로스펙션 쿼리를 실행합니다.
- 가져오기가 성공하면 쿼리 편집기에서 필드와 타입 제안이 활성화됩니다.
이후 선택 세트 안에서 입력하면 현재 타입에 실제로 존재하는 필드를 제안받을 수 있습니다.
query GetUser {
user(id: "usr_1024") {
# 여기에서 필드를 입력하면 스키마 기반 제안을 받을 수 있습니다.
}
}
주의할 점도 있습니다.
- 코드 완성은
스키마 가져오기를 실행한 뒤 활성화됩니다. - 프로덕션 서버에서 인트로스펙션을 비활성화했다면 스키마를 가져올 수 없습니다.
- API 스키마가 바뀌면 다시 가져와야 제안 목록이 최신 상태로 유지됩니다.
4. 요청 실행 및 응답 확인
전송을 클릭하면 하단 응답 영역에서 결과를 확인할 수 있습니다.
{
"data": {
"user": {
"id": "usr_1024",
"name": "Dana Whitfield",
"email": "dana@example.com",
"orders": [
{
"id": "ord_5001",
"total": 89.9,
"status": "SHIPPED",
"createdAt": "2026-07-01T09:14:00Z"
},
{
"id": "ord_5002",
"total": 12.5,
"status": "PENDING",
"createdAt": "2026-07-12T16:03:00Z"
}
]
}
}
}
GraphQL 응답에서는 결과가 일반적으로 data 아래에 있습니다.
data.user.id
data.user.orders
data.createOrder.status
오류는 data와 같은 레벨의 errors 배열로 반환될 수 있습니다.
{
"data": null,
"errors": [
{
"message": "..."
}
]
}
이 구조는 이후 JSONPath 어설션을 작성할 때 중요합니다.
요청을 재사용할 수 있도록 변수 전달하기
쿼리에 "usr_1024" 같은 값을 하드코딩하면 다른 사용자나 다른 환경에서 재사용하기 어렵습니다. GraphQL 변수로 값을 분리하세요.
GraphQL 변수 문법은 공식 GraphQL 변수 문서를 따릅니다.
먼저 쿼리 시그니처에 변수와 타입을 선언합니다.
query GetUserWithOrders($userId: ID!) {
user(id: $userId) {
id
name
orders {
id
total
status
}
}
}
그런 다음 Apidog의 변수 입력 영역에 JSON 객체를 넣습니다.
{
"userId": "usr_1024"
}
이제 쿼리를 수정하지 않고 변수 값만 바꿔 다른 사용자를 조회할 수 있습니다.
{
"userId": "usr_2048"
}
실무에서는 다음과 같이 사용하는 것이 좋습니다.
- 사용자 ID, 주문 ID, 검색어는 GraphQL 변수로 분리
- API 호스트, 토큰, 환경별 설정은 Apidog 환경 변수로 분리
- 스테이징과 프로덕션에서 동일한 요청을 재사용
- 테스트 시나리오에서는 이전 단계의 응답 값을 변수로 추출해 다음 단계에서 사용
주문 생성을 위한 뮤테이션 작성
뮤테이션은 데이터를 변경하는 GraphQL 작업입니다. 별도 탭이나 별도 HTTP 프로토콜이 필요한 것은 아닙니다.
같은 Query 입력 영역에서 query 대신 mutation 키워드를 사용하면 됩니다.
mutation CreateOrder($input: CreateOrderInput!) {
createOrder(input: $input) {
id
total
status
createdAt
}
}
뮤테이션 입력값은 변수 영역에 전달합니다.
{
"input": {
"userId": "usr_1024",
"items": [
{
"sku": "TSHIRT-BLK-M",
"quantity": 2
},
{
"sku": "MUG-CERAMIC",
"quantity": 1
}
],
"currency": "USD"
}
}
전송을 클릭한 뒤 다음과 같은 응답을 확인합니다.
{
"data": {
"createOrder": {
"id": "ord_5003",
"total": 42.3,
"status": "PENDING",
"createdAt": "2026-07-15T10:22:11Z"
}
}
}
뮤테이션은 실제 데이터를 변경하므로 프로덕션보다는 테스트 또는 스테이징 환경에서 실행하세요.
권장하는 검증 흐름은 다음과 같습니다.
- 사용자를 조회합니다.
- 주문 생성 뮤테이션을 실행합니다.
- 응답의 주문
id를 저장합니다. - 사용자를 다시 조회합니다.
- 생성한 주문이 주문 목록에 포함되는지 검증합니다.
이 쿼리-뮤테이션-쿼리 흐름은 단순한 API 호출 확인보다 현실적인 종단 간 테스트에 가깝습니다.
응답을 눈으로 확인하지 말고 어설션으로 검증하기
개발 중에는 JSON 응답을 직접 읽어도 됩니다. 하지만 CI나 스케줄러에서 실행할 테스트라면 자동으로 통과와 실패를 판별해야 합니다.
Apidog에서는 요청에 어설션을 추가할 수 있습니다. 설정 방식은 API 어설션을 참고하세요.
GraphQL 요청에는 최소한 다음 세 가지 어설션을 추가하세요.
1. HTTP 상태 코드가 200인지 확인
응답 상태 코드 = 200
이 검증은 필요하지만 충분하지 않습니다. GraphQL은 오류가 있어도 200을 반환할 수 있기 때문입니다.
2. errors 배열이 없는지 확인
GraphQL 작업의 성공 여부는 errors 배열을 반드시 확인해야 합니다.
errors 필드가 존재하지 않음
또는 Apidog의 JSONPath 기반 조건을 사용해 errors가 비어 있거나 없음을 검증합니다.
3. data 아래의 비즈니스 결과 확인
주문 생성 응답이라면 다음 경로를 검증할 수 있습니다.
$.data.createOrder.status
기대값:
PENDING
사용자 주문 조회라면 주문 목록이 비어 있지 않은지 확인합니다.
$.data.user.orders
예를 들어 배열 길이가 0보다 큰지 검증할 수 있습니다.
GraphQL 테스트에서 자주 사용하는 검증 항목은 다음과 같습니다.
| 검증 대상 | 예시 JSONPath | 기대 조건 |
|---|---|---|
| 사용자 ID | $.data.user.id |
값이 존재함 |
| 주문 상태 | $.data.createOrder.status |
PENDING과 같음 |
| 주문 목록 | $.data.user.orders |
길이가 0보다 큼 |
| GraphQL 오류 | $.errors |
존재하지 않음 |
상태 코드만 검사하면 200 OK와 함께 errors를 반환하는 실패를 놓칠 수 있습니다. 반드시 errors와 data 내부 값을 함께 검증하세요.
테스트 시나리오로 저장하기
단일 GraphQL 요청에 어설션을 추가하면 스모크 테스트가 됩니다. 더 실용적인 방법은 여러 요청을 하나의 시나리오로 연결하는 것입니다.
예를 들어 다음 순서로 구성할 수 있습니다.
- 사용자 조회
- 주문 생성
- 뮤테이션 응답에서 주문
id추출 - 사용자 재조회
- 새 주문이 목록에 포함되었는지 검증
Apidog 테스트 시나리오에서는 단계 간에 데이터를 전달할 수 있습니다. 주문 생성 단계의 응답에서 id를 추출해 변수로 저장하고, 다음 쿼리에서 그 값을 참조하는 방식입니다.
각 단계에는 앞에서 설명한 어설션을 추가하세요.
- HTTP 상태 코드가 200인지 확인
-
errors가 없는지 확인 - 필요한
data값이 존재하거나 기대값과 일치하는지 확인
테스트 시나리오 작성 방법은 Apidog으로 테스트 시나리오 작성 방법을 참고하세요.
GraphQL 도입 전 다른 API 스타일과 비교해야 한다면 다음 자료도 참고할 수 있습니다.
Apidog CLI로 워크플로우 자동화
GraphQL 요청과 테스트 시나리오를 프로젝트에 저장했다면 Apidog CLI를 통해 터미널 또는 CI 러너에서 시나리오를 실행할 수 있습니다.
먼저 CLI를 설치하고 로그인합니다.
npm install -g apidog-cli
apidog login --with-token <your-token>
그다음 저장된 테스트 시나리오를 ID와 환경 ID로 실행합니다.
apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
주요 옵션은 다음과 같습니다.
| 옵션 | 설명 |
|---|---|
-t |
테스트 시나리오 ID |
-e |
환경 ID |
-r |
리포터 형식 |
리포터는 cli, html, junit 등을 사용할 수 있습니다.
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t <scenario_id> \
-e <env_id> \
-r html,cli
CLI는 클라우드 프로젝트에 저장된 시나리오와 테스트 스위트를 실행하고 결과를 보고합니다. 다만 CLI 문서는 HTTP 시나리오 실행을 명시적으로 다루며, GraphQL 단계가 포함된 시나리오의 헤드리스 실행 지원 여부를 명확히 설명하지는 않습니다.
따라서 다음처럼 접근하는 것이 안전합니다.
- GraphQL 쿼리, 뮤테이션, 스키마 가져오기, 어설션 설정은 Apidog 앱에서 구성
- CI 실행 전 GraphQL 포함 시나리오가 프로젝트 환경에서 정상 실행되는지 확인
- CLI는 저장된 회귀 시나리오 실행과 사양 동기화에 활용
-
import명령으로 OpenAPI, HAR, Postman 등의 정의를 동기화
토큰 설정은 Apidog CLI 설치 가이드를, GitHub Actions 연결은 GitHub Actions 파이프라인의 Apidog CLI를 참고하세요.
자주 묻는 질문
Apidog에서 GraphQL을 테스트하려면 유료 플랜이 필요한가요?
GraphQL 요청 문서는 이 기능을 특정 플랜이나 클라우드·자체 호스팅 환경으로 제한한다고 명시하지 않습니다. 무료 티어부터 시작할 수 있으며, 최신 플랜 정보는 Apidog에서 확인하세요.
GraphQL 요청이 200을 반환하는데도 실패하는 이유는 무엇인가요?
GraphQL에서는 HTTP 전송이 성공하면 200을 반환할 수 있습니다. 하지만 쿼리의 필드명, 변수, 권한 또는 비즈니스 규칙에 문제가 있으면 응답 본문의 errors 배열에 오류가 포함됩니다.
따라서 상태 코드뿐 아니라 errors가 없는지도 항상 검증해야 합니다. 자세한 방식은 API 어설션을 참고하세요.
쿼리 작성 중 필드 제안을 받으려면 어떻게 하나요?
GraphQL 요청 편집기에서 스키마 가져오기를 클릭하세요. Apidog이 인트로스펙션을 수행한 뒤 코드 완성을 활성화합니다.
스키마가 변경된 경우에는 다시 가져와야 합니다. 서버에서 인트로스펙션을 비활성화했다면 API 문서를 기준으로 필드를 수동으로 작성해야 합니다.
뮤테이션은 어디에 작성하나요?
별도의 뮤테이션 탭은 없습니다. 기존 Query 입력 영역에 query 대신 mutation 키워드를 사용해 작성합니다.
mutation CreateOrder($input: CreateOrderInput!) {
createOrder(input: $input) {
id
}
}
입력 데이터는 변수 JSON으로 전달한 뒤 전송을 클릭하면 됩니다.
쿼리를 수정하지 않고 다른 값을 전달하려면 어떻게 하나요?
GraphQL 변수를 사용하세요.
query GetUser($userId: ID!) {
user(id: $userId) {
id
name
}
}
{
"userId": "usr_1024"
}
이 문법은 표준 GraphQL 변수 사양을 따릅니다. Apidog 환경 변수와 함께 사용하면 같은 요청을 스테이징과 프로덕션 환경에서 재사용할 수 있습니다.
마무리
GraphQL 테스트를 구현할 때는 다음 순서를 기준으로 작업하세요.
- GraphQL 요청을
POST와GraphQL본문 유형으로 생성합니다. -
Query영역에 쿼리 또는 뮤테이션을 작성합니다. - 스키마를 가져와 필드명과 타입 오류를 줄입니다.
- 하드코딩 값을 GraphQL 변수로 분리합니다.
- HTTP 상태 코드뿐 아니라
errors와data내부 값도 어설션합니다. - 쿼리와 뮤테이션을 테스트 시나리오로 연결합니다.
- 필요하면 CLI와 CI 파이프라인으로 반복 실행합니다.
사용자 조회 → 주문 생성 → 주문 재조회 흐름을 하나의 시나리오로 저장해 두면, 스키마나 백엔드 로직이 변경될 때마다 재실행할 수 있는 GraphQL 회귀 테스트 기반을 만들 수 있습니다.
Top comments (0)