GraphQL API Testing Guide: Complete 2026 Handbook
Complete 2026 GraphQL API testing guide. Schema validation, query testing, mutation testing, security testing, and tooling for Jest, Postman, and Karate.

This guide covers everything you need to test GraphQL APIs in 2026: schema validation, queries, mutations, security, and tooling. For the broader picture, see our API Testing Tutorial, Microservices Testing Strategy, and Postman API Testing Tutorial.
What is GraphQL?
GraphQL is a query language for APIs that lets clients request exactly the data they need. Developed by Facebook in 2012 and open-sourced in 2015, it's now the default choice for many product teams alongside REST.
Why GraphQL Testing Is Different
- Single endpoint — every request goes to
/graphql. - POST method — all queries are POSTs.
- Query in body — GraphQL operations travel in the request body.
- Schema-driven — tests can introspect the schema.
- Variable support — operations accept typed variables.
- Subscriptions — real-time data over WebSocket.
GraphQL Test Layers
| Layer | What to test |
|---|---|
| Schema | Types, fields, arguments, enums |
| Queries | Happy path, edge cases, errors |
| Mutations | Create, update, delete operations |
| Subscriptions | Real-time event delivery |
| Security | Authentication, authorization, injection |
How to Test Queries
Simple query
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}const query = `
query GetUser($id: ID!) {
user(id: $id) { id name email }
}
`;
const variables = { id: '123' };
const response = await fetch('https://api.example.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables }),
});
const json = await response.json();
expect(json.data.user.id).toBe('123');Query with variables
query SearchUsers($term: String!, $limit: Int = 10) {
searchUsers(term: $term, limit: $limit) { id name }
}How to Test Mutations
Create
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) { id name email }
}const variables = {
input: { name: 'Alice', email: 'alice@example.com', role: 'admin' }
};Update
mutation UpdateUser($id: ID!, $input: UpdateUserInput!) {
updateUser(id: $id, input: $input) { id name email }
}Schema Validation
Validate with graphql-js
import { buildSchema, validate, parse } from 'graphql';
const schema = buildSchema(`
type Query { user(id: ID!): User }
type User { id: ID! name: String! email: String! }
`);
const query = `query { user(id: "123") { id name email } }`;
const errors = validate(schema, parse(query));
expect(errors).toHaveLength(0);Detect breaking changes with graphql-inspector
const inspector = new GraphQLInspector();
const changes = inspector.diff(oldSchema, newSchema);
// breaking, dangerous, and safe changesError Testing
const query = `query { user(id: "invalid") { id } }`;
const response = await graphqlCall(query);
expect(response.errors).toBeDefined();
expect(response.errors[0].message).toContain('Invalid ID');| Error | Cause |
|---|---|
| Syntax Error | Invalid query syntax |
| Validation Error | Query against invalid schema |
| Execution Error | Server-side error |
| Authentication Error | Missing/invalid auth |
| Authorization Error | User lacks permission |
Security Testing
1. Introspection disabled in production
const query = `{ __schema { types { name } } }`;
const response = await graphqlCall(query);
expect(response.errors[0].message).toContain('not allowed');2. Query depth limit
const deep = `query { user { friends { friends { friends { friends { name } } } } } }`;
// expect depth limit error3. Query complexity limit
const expensive = `query { users(first: 10000) { id name posts { title } comments { text } } }`;
// expect complexity error4. SQL injection in GraphQL
query { user(id: "1' OR '1'='1") { id name } }Expected: validation error or sanitized response.
5. Auth required for sensitive fields
const response = await graphqlCall(`{ adminUsers { id email } }`);
expect(response.errors[0].message).toContain('Unauthorized');Tools for GraphQL Testing
Postman
Native GraphQL support: POST to your endpoint, JSON body with query + variables, write assertions in the Tests tab. See the Postman API Testing Tutorial.
Jest + graphql-request
import { request } from 'graphql-request';
const endpoint = 'https://api.example.com/graphql';
test('returns user by id', async () => {
const query = `query GetUser($id: ID!) { user(id: $id) { id name } }`;
const data = await request(endpoint, query, { id: '123' });
expect(data.user.id).toBe('123');
});Karate DSL
Feature: User API
Scenario: Get user
Given path '/graphql'
And request { query: 'query { user(id: "123") { id name } }' }
When method POST
Then status 200
And match $.data.user.id == '123'Apollo Studio
Visual GraphQL explorer for running queries, browsing the schema, and generating tests. See official Apollo Studio docs and graphql.org learn.
Test Pyramid for GraphQL
Unit
- Schema validation.
- Single-field queries.
- Edge cases (null, empty, max values).
Integration
- Full query chains.
- Mutations.
- Authentication and authorization.
E2E
- Full user journeys.
- Subscription delivery.
- Real backend, real database.
For the broader pyramid, see Test Pyramid Explained.
Common Mistakes and Fixes
- Testing only the happy path — add error, security, and edge cases.
- Leaving introspection enabled in production — disable it.
- No query depth/complexity limits — use
graphql-depth-limit:const depthLimit = require('graphql-depth-limit'); const server = new ApolloServer({ validationRules: [depthLimit(7)] }); - Not testing subscriptions — verify real-time events actually deliver.
- Ignoring N+1 query problems — assert query count, not just response.
- Not validating input data — use the type system and
@constraintdirectives. - No rate limiting — protect the single endpoint.
- Trusting client-side validation — always re-validate on the server.
How to Start Testing GraphQL
Step 1 — Install tools
npm install --save-dev graphql graphql-request jestStep 2 — Write your first test
test('user query returns expected fields', async () => {
const query = `{ user(id: "1") { id name email } }`;
const response = await graphqlCall(query);
expect(response.data.user.id).toBe('1');
});Step 3 — Add error tests
test('invalid id returns error', async () => {
const response = await graphqlCall(`{ user(id: "invalid") { id } }`);
expect(response.errors).toBeDefined();
});Step 4 — Add security tests
test('introspection is disabled in production', async () => {
const response = await graphqlCall(`{ __schema { types { name } } }`);
expect(response.errors[0].message).toContain('not allowed');
});Step 5 — Wire into CI/CD
Run on every PR. See the GitHub Actions Automation Testing guide.
Keep Learning
Continue your API testing journey: API Testing Tutorial · Microservices Testing Strategy · Postman API Testing · API testing interview questions · AI mock interview.
Frequently asked questions
1.What is GraphQL?
2.How is GraphQL testing different from REST testing?
3.What tools should I use for GraphQL testing in 2026?
4.How do I test GraphQL security?
5.Can I use Postman for GraphQL testing?
6.What's the #1 GraphQL testing mistake?
Practice these questions
Rehearse REST, Postman, REST Assured and contract-testing questions with worked examples.
Was this article helpful?
More from REST API Testing
REST fundamentals — verbs, status codes, contracts.
- Experience-Level QA InterviewsAPI Testing Interview Questions for 1 Year Experience (2026 Complete Guide)
- Experience-Level QA InterviewsAPI Testing Interview Questions for 3 Years Experience (2026 Complete Guide)
- Experience-Level QA InterviewsAPI Testing Interview Questions for Senior Level (2026 Complete Guide)
Keep building your QA edge
Pillar guides- Postman TutorialPostman API testing tutorialPostman from zero to CI — collections, scripts, Newman.
- cURL to Code Converterconvert cURL to Postman, Playwright, or Rest AssuredConvert any cURL command to Postman, Playwright, Rest Assured, k6, Cypress, Python, and more — free, in-browser.
- JSON / JSONPath / JMESPath Testertest JSONPath and JMESPath side by sideDual-engine JSONPath + JMESPath tester with assertion builder and Postman/Playwright/Rest Assured export.
- Postman to Code ConverterPostman collection to code converterConvert any Postman collection into a full Playwright, Rest Assured, k6, Cypress, Supertest, Python, or Karate test suite — folders, pm.test assertions, and environments preserved.
- API Tester RoleAPI Tester career path and salaryAPI Tester career guide — Postman, REST Assured, contract testing, and pay.
Practice these questions live
Rehearse with an AI QA interviewer that scores your answers in real time.
Continue reading
Related concepts, tools & standards around API Testing
A quick reference of the people, companies, frameworks and technologies most often mentioned alongside API Testing in real QA teams — useful when you're mapping a learning path, preparing for interviews, or scoping a new project.
Join the QA Community
Connect with fellow testers, share job leads, and get career advice.



Discussion
Ask a question, share your experience, or correct us. Be kind — real people are reading.