GraphQL 엔드포인트가 있고, 그것이 작동하는지 확인해야 합니다. 단순히 "서버가 켜져 있다"는 것이 아니라, 실제 앱이 읽는 필드를 user 쿼리가 반환하는지, createOrder 뮤테이션이 실제로 주문을 저장하는지, 변수를 변경할 때 데이터 구조가 유지되는지 확인해야 합니다. 경로와 동사 호출만 아는 REST 도구로는 이러한 테스트가 어렵습니다. GraphQL은 모든 것을 POST 본문으로 단일 URL에 전송하므로, 쿼리 언어 자체를 이해하고, 필드 제안을 제공하며, 반환되는 JSON에 대해 어설션을 할 수 있는 클라이언트가 필요합니다.
Apidog은 HTTP, gRPC, WebSocket, SSE, SOAP와 함께 GraphQL을 일등 시민 요청 유형으로 처리합니다. 이 가이드는 GraphQL 요청을 처음부터 구축하는 과정을 안내합니다: 쿼리 작성, 코드 완성을 위한 스키마 가져오기, 변수 전달, 뮤테이션 실행, 응답에 대한 어설션 설정. 예시로는 사용자와 주문을 쿼리하고 새 주문을 생성하는 전자상거래 API를 사용합니다. GraphQL이 여러 엔드포인트 대신 단일 타입 쿼리를 보내는 이유에 대한 개념적 배경을 알고 싶다면, 공식 GraphQL 문서가 정식 참고 자료이며, REST 대 GraphQL 비교 글에서 각 방식이 적합한 경우를 다룹니다.
테스트하는 것과 GraphQL이 다른 이유
REST는 각각 고정된 형태를 반환하는 많은 엔드포인트를 제공합니다. GraphQL은 하나의 엔드포인트를 제공하고 호출자가 원하는 필드를 정확히 요청할 수 있도록 합니다. 이러한 유연성이 핵심이며, 테스트를 다르게 느끼게 하는 이유이기도 합니다.
두 가지가 달라집니다. 첫째, 요청은 변경 가능한 URL이 아니라 본문에 있는 쿼리 문서입니다. GET /users/42는 POST로 전송되는 user(id: 42) { ... } 선택으로 바뀝니다. 둘째, GraphQL은 비즈니스 오류에 대해 거의 200이 아닌 상태를 반환하지 않습니다. 실패한 쿼리도 JSON의 errors 배열과 함께 200 OK로 돌아옵니다. 따라서 상태 코드만 확인하는 것으로는 충분하지 않습니다. 본문을 읽어야 합니다. 이 단일 사실이 이 가이드의 뒷부분에서 어설션을 설정하는 방식에 영향을 미칩니다.
Apidog은 전용 GraphQL 본문 유형, 스키마 인식 코드 완성, 재사용 가능한 쿼리용 변수, 그리고 REST에 사용하는 것과 동일한 어설션 및 테스트 시나리오 도구를 제공합니다. 앱에서 요청을 설계하고 실행한 다음, 다시 실행할 수 있는 시나리오로 저장할 수 있습니다. 하나 만들어 봅시다.
Apidog에서 GraphQL 요청 생성하기
먼저, Apidog을 다운로드하거나 브라우저에서 열고 프로젝트를 엽니다. 처음 시작하는 경우, 요청이 저장될 공간을 위해 프로젝트를 생성하세요.
1단계: 새 요청을 만들고 본문을 GraphQL로 전환
+ 버튼을 클릭하고 새 요청을 선택합니다. 그러면 REST 호출에 사용하는 것과 동일한 표준 요청 빌더(메서드, URL, 매개변수, 인증)가 열립니다.
메서드를 POST로 설정하고 GraphQL 엔드포인트를 URL 바에 붙여넣습니다. 일반적인 형태는 다음과 같습니다:
https://api.yourstore.com/graphql
이제 Apidog에 이것이 GraphQL 요청임을 알립니다. 요청 본문 영역에서 Body를 클릭한 다음 GraphQL을 선택합니다. 본문 편집기가 쿼리 언어가 있는 Query 상자와 함께 GraphQL 인식 보기로 변경됩니다.
엔드포인트에 토큰이 필요한 경우, 인증 섹션을 열고 Bearer 토큰과 같이 토큰을 추가합니다. GraphQL 요청의 인증은 Apidog의 다른 HTTP 요청과 동일하게 작동하는데, 내부적으로 여전히 HTTP POST이기 때문입니다.
2단계: 첫 번째 쿼리 작성
실행 탭에서 Query 상자에 쿼리를 입력합니다. 구체적인 것부터 시작해 보세요. 여기서는 사용자와 그 사용자에게 연결된 주문을 원합니다:
query GetUserWithOrders {
user(id: "usr_1024") {
id
name
email
orders {
id
total
status
createdAt
}
}
}
이것은 한 명의 사용자와 그들의 중첩된 주문 목록을 요청합니다. 필드 이름은 서버의 스키마와 정확히 일치해야 합니다. 스키마에서 email 대신 emailAddress라고 부르면 이 쿼리는 실패합니다. 이는 다음 단계에서 방지해야 할 부분입니다.
3단계: 코드 완성을 위해 스키마 가져오기
필드 이름을 추측하는 것은 GraphQL 테스트가 느려지는 지점입니다. Apidog은 스키마를 읽어 사용자가 입력할 때 다른 탭에서 문서를 교차 확인하는 대신 유효한 필드와 유형을 편집기가 제안하도록 할 수 있습니다.
이것은 수동으로 요청 시 수행되는 작업입니다. 입력 상자의 스키마 가져오기 버튼을 클릭하세요. Apidog은 엔드포인트에 대해 인트로스펙션 쿼리를 실행하고 타입 시스템을 가져옵니다. 성공하면 코드 완성이 활성화됩니다. 선택 내에서 필드를 입력하기 시작하면 해당 타입에서 실제로 사용 가능한 것에 대한 IntelliSense 스타일 제안을 받게 됩니다.
알아두면 좋은 두 가지 사항이 있습니다. 코드 완성은 자동으로 되지 않습니다. 스키마 가져오기를 클릭한 후에만 활성화됩니다. 그리고 엔드포인트에서 인트로스펙션이 비활성화된 경우(일부 프로덕션 서버는 보안을 위해 그렇게 합니다), 가져오기가 스키마를 반환하지 않으므로 자체 문서에 따라 필드를 수동으로 작성해야 합니다. 가져오기가 작동하는 경우, 스키마 변경 후에는 다시 가져와서 제안이 최신 상태를 유지하도록 하세요.
4단계: 실행하고 응답 읽기
전송을 클릭합니다. 응답은 인터페이스의 하단에 나타납니다. 정상적인 결과는 다음과 같습니다:
{
"data": {
"user": {
"id": "usr_1024",
"name": "Dana Whitfield",
"email": "dana@example.com",
"orders": [
{ "id": "ord_5001", "total": 89.90, "status": "SHIPPED", "createdAt": "2026-07-01T09:14:00Z" },
{ "id": "ord_5002", "total": 12.50, "status": "PENDING", "createdAt": "2026-07-12T16:03:00Z" }
]
}
}
}
최상위 data 키에 주목하세요. 모든 GraphQL 응답은 결과를 data 아래에 중첩하고, 모든 문제는 형제 관계인 errors 배열에 나타납니다. 이 구조를 염두에 두십시오. 어설션은 루트가 아닌 data.user...를 가리킬 것이기 때문입니다.
요청 재사용을 위한 변수 전달
쿼리에 "usr_1024"를 하드코딩하는 것은 한 번만 작동합니다. 여러 사용자 및 환경에서 다시 실행할 요청의 경우, 해당 값을 변수로 옮기십시오. GraphQL에는 이를 위한 일등 시민 변수 구문이 있으며, Apidog은 이를 지원합니다. 구문 자체는 Apidog의 발명이 아닌 표준 GraphQL이므로, 변수에 대한 공식 GraphQL 문서가 진실의 원천입니다.
쿼리 시그니처에 $ 접두사와 타입을 사용하여 변수를 선언한 다음, 인자에서 사용합니다:
query GetUserWithOrders($userId: ID!) {
user(id: $userId) {
id
name
orders {
id
total
status
}
}
}
그런 다음 변수의 작은 JSON 객체로 값을 제공합니다:
{
"userId": "usr_1024"
}
이제 하나의 JSON 값만 변경하면 어떤 사용자에 대해서든 동일한 쿼리가 실행됩니다. 이를 Apidog 환경 변수와 함께 사용하면 쿼리를 편집할 필요 없이 동일한 요청을 스테이징 및 프로덕션 환경에 보낼 수 있습니다. 이것이 일회성 호출을 저장하고, 공유하며, 스위트에서 실행할 수 있는 것으로 바꾸는 방법입니다.
주문 생성을 위한 뮤테이션 작성
뮤테이션은 데이터를 변경합니다. GraphQL에는 이를 위한 별도의 프로토콜이나 UI가 없습니다. 뮤테이션은 query 키워드 대신 mutation 키워드를 사용하여 동일한 Query 상자에 GraphQL로 작성됩니다. 따라서 이미 알고 있는 워크플로우가 그대로 적용됩니다.
여기서는 이전에 쿼리했던 사용자를 위한 주문을 생성합니다:
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.30,
"status": "PENDING",
"createdAt": "2026-07-15T10:22:11Z"
}
}
}
뮤테이션은 실제 데이터를 작성하므로, 프로덕션 환경이 아닌 테스트 또는 스테이징 환경에서 실행해야 합니다. 일반적인 패턴은 뮤테이션을 실행하고, 반환된 id를 캡처한 다음, GetUserWithOrders 쿼리를 다시 실행하여 새 주문이 목록에 나타나는지 확인하는 것입니다. 이 쿼리-뮤테이션-쿼리 루프는 현실적인 종단 간 확인이며, 다음 섹션에서 시나리오로 저장하고 싶을 만한 종류의 것입니다.
육안 확인 대신 응답에 대한 어설션 설정
탐색하는 동안 JSON을 수동으로 읽는 것은 괜찮습니다. 무인으로 실행되는 테스트의 경우, 자체적으로 통과 또는 실패하는 어설션이 필요합니다. Apidog은 요청에 어설션을 추가하여 실행이 자동으로 판단되도록 하며, 이는 API 어설션에서 설정하는 내용입니다.
GraphQL의 경우, 세 가지 확인으로 대부분의 경우를 다룹니다:
- HTTP 상태가
200인지 어설션합니다. GraphQL은 비즈니스 오류에서도 200을 반환하므로 필수적이지만 충분하지는 않습니다. errors필드가 없는지 어설션합니다. 이것이 실제 GraphQL의 성공 또는 실패 지점입니다.errors가 존재한다면, 상태가 무엇이든 관계없이 작업이 실패한 것입니다.data내의 특정 값에 대해 어설션합니다. 예를 들어, JSONPath를 사용하여$.data.createOrder.status가PENDING과 같거나,$.data.user.orders의 길이가 0보다 큰지 확인합니다.
이 조합은 상태 코드만으로는 놓칠 수 있는 실패 모드를 잡아냅니다: errors 배열과 함께 200을 반환하는 쿼리 또는 성공했지만 잘못된 형태를 반환하는 쿼리. 값 어설션은 이전에 보았던 응답 구조와 일치하도록 data 아래의 중첩된 경로를 가리키도록 설정하십시오.
테스트 시나리오로 저장하기
단일 어설션 요청은 좋은 스모크 테스트입니다. 진정한 가치는 요청들을 시나리오로 연결하는 데 있습니다: 사용자를 쿼리하고, 주문을 생성한 다음, 다시 쿼리하여 주문이 지속되었는지 확인하는 것입니다. Apidog 테스트 시나리오를 사용하면 이러한 단계를 순서대로 연결하고, 데이터(뮤테이션에서 id를 캡처하여 확인 쿼리에 전달)를 주고받으며, 전체 흐름을 한 번의 클릭으로 실행할 수 있습니다. 자세한 내용은 Apidog으로 테스트 시나리오 작성 방법에 있습니다.
개략적으로 설명하자면: 새 테스트 시나리오를 생성하고, GraphQL 쿼리 및 뮤테이션을 순서대로 단계로 추가하고, 뮤테이션 응답에서 주문 id를 변수로 추출한 다음, 최종 쿼리 단계에서 해당 변수를 참조합니다. 이전 섹션의 어설션을 각 단계에 추가합니다. 이제 사람, 스케줄러 또는 파이프라인이 실행할 수 있는 GraphQL API에 대한 반복 가능한 회귀 테스트를 갖게 될 것입니다.
구현하기 전에 GraphQL을 다른 스타일과 비교하는 팀을 위해, REST 대 GraphQL 대 gRPC 분석과 GraphQL 테스트 및 목업 도구에 대한 총정리 글 모두 이 워크플로우를 이해하는 데 도움이 될 것입니다. 스택에 SOAP도 포함되어 있다면, Apidog에서 SOAP API 테스트하는 방법에 동일한 요청 및 어설션 패턴이 적용됩니다.
Apidog CLI로 워크플로우 자동화
GraphQL 시나리오가 프로젝트에 저장되면 Apidog CLI를 사용하여 터미널 또는 CI 러너에서 프로젝트에 저장된 테스트 시나리오를 실행할 수 있습니다. 설치하고 로그인하세요:
npm install -g apidog-cli
apidog login --with-token <your-token>
그런 다음 환경을 지정하여 id로 저장된 시나리오를 실행합니다:
apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
여기서 -t는 테스트 시나리오 ID이고, -e는 환경 ID이며, -r은 리포터(cli, html 또는 junit; 여러 개일 경우 -r html,cli와 같이 쉼표로 구분)입니다. CLI는 클라우드 프로젝트에서 저장된 시나리오 및 테스트 스위트를 실행하고 성공 또는 실패를 보고하며, 이는 Apidog을 빌드에 연결하는 역할을 합니다. 한 가지 솔직한 주의 사항: CLI 문서는 HTTP 시나리오 실행을 확인하지만, GraphQL 단계를 포함하는 시나리오가 헤드리스로 실행되는지는 명시하지 않습니다. CLI는 HTTP 회귀 실행을 위한 엔진이자 import 명령(OpenAPI, HAR, Postman 등)을 통해 사양을 동기화하는 도구로 활용하고, GraphQL 쿼리, 뮤테이션 및 어설션 작업은 앱에서 수행하십시오. 토큰 설정은 Apidog CLI 설치 가이드를, CI에 연결하는 방법은 GitHub Actions 파이프라인의 Apidog CLI를 참조하십시오.
자주 묻는 질문
Apidog에서 GraphQL을 테스트하려면 유료 플랜이 필요한가요? GraphQL 요청 문서는 이 기능을 특정 플랜 계층으로 제한하지 않으며, 클라우드 대 자체 호스팅에 대한 선을 긋지도 않습니다. 무료 티어에서 시작할 수 있습니다: 신용 카드 없이 무료로 사용해보고, 현재 플랜 세부 정보는 Apidog에서 확인하세요.
GraphQL 요청이 200을 반환하는데도 실패하는 이유는 무엇인가요? 이는 일반적인 GraphQL 동작입니다. 전송은 성공했으므로 HTTP 상태는 200이지만, 작업이 비즈니스 또는 유효성 검사 오류에 부딪혀 JSON 본문의 errors 배열에 표시된 것입니다. API 어설션에서 다룬 바와 같이, 상태를 확인하는 것 외에도 errors가 없는지 항상 어설션해야 합니다.
쿼리 작성 중 필드 제안을 어떻게 받을 수 있나요? 입력 상자의 스키마 가져오기 버튼을 클릭하세요. Apidog이 엔드포인트를 인트로스펙션하여 코드 완성을 활성화하므로 편집기가 유효한 필드와 타입을 제안합니다. 이는 자동이 아닌 수동 단계이므로, 엔드포인트 URL이 설정되면 클릭하고, 스키마 변경 후에는 다시 가져와야 합니다.
뮤테이션은 어디에 작성하나요? 별도의 뮤테이션 탭이 보이지 않습니다. 별도의 탭은 없습니다. 뮤테이션은 query 키워드 대신 mutation 키워드를 사용하여 동일한 Query 상자에 GraphQL로 작성됩니다. 페이로드를 변수를 통해 전달한 다음, 쿼리처럼 전송을 클릭합니다.
쿼리를 다시 작성하지 않고 다른 값을 전달하려면 어떻게 해야 하나요? GraphQL 변수를 사용하세요. 작업 시그니처에 $ 접두사와 함께 선언하고 값의 JSON 객체를 제공합니다. 구문은 표준 GraphQL 사양을 따르며, Apidog의 변수 지원은 환경 변수와 함께 작동하여 하나의 요청이 스테이징 및 프로덕션 환경에서 실행될 수 있도록 합니다.
마무리
GraphQL 테스트는 몇 가지 성실한 습관으로 요약됩니다: Query 상자에 쿼리를 작성하고, 편집기가 도움이 되도록 스키마를 가져오고, 고정 값을 변수로 옮기고, 상태 코드를 신뢰하는 대신 본문에 대해 어설션합니다. 쿼리를 실행하는 것과 같은 방식으로 뮤테이션을 실행한 다음, 둘 다 저장된 시나리오로 연결하여 검사를 반복합니다. Apidog을 다운로드하여 위에서 설명한 사용자-주문 흐름을 구축하면, 스키마가 변경될 때마다 다시 실행할 수 있는 GraphQL 회귀 테스트를 갖게 될 것입니다.
