GraphQL API Testing — Query Validation, Mutation Testing, and Schema Analysis
In this tutorial, you will learn about GraphQL API Testing. We cover key concepts, practical examples, and best practices to help you master this topic.
GraphQL API testing validates queries, mutations, and subscriptions against a schema, ensuring data integrity, error handling, and performance under varying query complexities.
What You'll Learn
- How to write and test GraphQL queries and mutations
- Techniques for response validation and error handling
- Performance testing strategies for GraphQL APIs
Why It Matters
Unlike REST, GraphQL exposes a flexible query language that shifts validation responsibility to the client. Testing must cover schema correctness, query depth limits, and resolver performance.
Real-World Use
An e-commerce platform uses GraphQL to let mobile apps fetch product data, cart mutations, and order submissions. Tests validate every query against the schema and measure resolver response times.
flowchart TD
A[GraphQL Schema] --> B[Query Validation]
A --> C[Mutation Testing]
A --> D[Subscription Testing]
B --> E[Response Assertion]
C --> E
D --> E
E --> F[Performance Check]
F --> G[Pass/Fail]
Testing a GraphQL Query
Let's test a simple GraphQL query that fetches products.
import requests
url = "https://api.example.com/graphql"
query = """
query {
products(category: "electronics", limit: 5) {
id
name
price
}
}
"""
response = requests.post(url, json={"query": query})
data = response.json()
assert "data" in data
assert len(data["data"]["products"]) <= 5
assert response.status_code == 200
Expected output: No assertion errors if the API returns products correctly.
Testing a GraphQL Mutation
Mutations modify server-side data. Test that a product mutation succeeds and returns the expected shape.
mutation = """
mutation {
addProduct(name: "Wireless Mouse", price: 29.99, category: "electronics") {
id
name
price
}
}
"""
response = requests.post(url, json={"query": mutation})
result = response.json()["data"]["addProduct"]
assert "id" in result
assert result["name"] == "Wireless Mouse"
assert result["price"] == 29.99
Expected output: The mutation returns the created product with a generated id.
Testing Error Handling
GraphQL returns errors in the errors field rather than HTTP status codes. Test that invalid queries return meaningful messages.
bad_query = """
query {
nonExistentField {
id
}
}
"""
response = requests.post(url, json={"query": bad_query})
body = response.json()
assert "errors" in body
assert any("Cannot query field" in e["message"] for e in body["errors"])
assert response.status_code == 200 # GraphQL always returns 200
Expected output: The errors array contains a field validation message.
Common Mistakes
| Mistake | Why It's Wrong |
|---|---|
| Checking HTTP 400 for errors | GraphQL always returns 200 with errors in the response body |
| Hardcoding query variables | Different environments need different variable values |
| Ignoring nullable fields | A field may be null in some responses but not others |
| Not testing query depth | Deeply nested queries can degrade server performance |
| Skipping mutation side effects | Mutations change data; test that the change persists |
| Assuming field order | GraphQL fields may arrive in any order |
| Not validating schema changes | Schema updates can break existing queries silently |
Practice Questions
- What HTTP status code does a GraphQL endpoint return when a query fails?
A: 200. Errors are returned in the
errorsarray of the response body. - How do you pass variables to a GraphQL query?
A: Include a
variableskey in the POST body alongside thequerykey. - What is schema introspection and why test it? A: Introspection queries reveal the full schema. Test it to verify production introspection is disabled.
- How does GraphQL handle nullable vs non-nullable fields?
A: Non-nullable fields (marked with
!) must return a value; nullable fields may return null. - What is query complexity analysis? A: A technique to reject expensive queries before execution based on depth and field cost.
Challenge
Write a test that sends a deeply nested query with 10 levels of nesting, then asserts that the API rejects it with a complexity error.
FAQ
What is a resolver in GraphQL?
A resolver is a function that fetches data for a specific field. Each field in the schema has a corresponding resolver.
How do you test GraphQL subscriptions?
Subscriptions use WebSockets. Test by connecting a client, subscribing to an event, and triggering the event via a mutation.
Can you use Postman for GraphQL testing?
Yes. Postman supports GraphQL queries natively with schema autocomplete and variable management.
What is Apollo Studio?
Apollo Studio is a managed platform for schema exploration, query tracing, and performance monitoring of GraphQL APIs.
How do you mock a GraphQL API for testing?
Use tools like apollo-server or graphql-tools to create a mock schema with fake resolvers.
What is the N+1 Problem in GraphQL?
A performance issue where a resolver makes N+1 database calls for N items. Tools like DataLoader batch queries to solve this.
How do you test authorization in GraphQL?
Send queries with different authentication tokens and assert that restricted fields return null or errors.
Mini Project
Build a test suite for a GraphQL API that handles blog posts. Include query tests, mutation tests for create/update/delete, error handling for invalid fields, and a performance test that measures response time for complex queries.
What's Next
Now that you understand GraphQL testing, move on to Websocket API testing for real-time applications.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro