Why GraphQL testing is different from REST
- One endpoint, infinite requests. There's no URL list to cover — the test surface is the schema: every type, field, argument and resolver combination.
- 200 doesn't mean success. GraphQL returns HTTP 200 even when resolvers fail, with failures in an
errorsarray and possibly partial data beside them. Status-code assertions from REST tooling pass while everything is on fire. - Clients control cost. A consumer can request ten nested levels of relations in one query. Depth, complexity and the N+1 resolver problem are attack and outage vectors REST simply doesn't have.
- Auth goes per-field. Two users running the same query legitimately get different shapes back. Authorization must be tested at field granularity.
What to test in a GraphQL API
| Layer | What to verify |
|---|---|
| Queries | Correct data for valid selections; sensible nulls; pagination behavior; aliases and fragments resolve. |
| Mutations | State actually changes; response reflects the change; invalid input rejected with typed errors; idempotency where promised. |
| Error semantics | errors array is populated correctly, partial data behaves as documented, and internal details never leak into messages. |
| Authorization | Field-level access rules hold for every role; introspection is appropriately restricted in production. |
| Performance | Deep/complex queries are bounded (depth and cost limits); hot queries meet latency budgets; N+1 patterns caught under load. |
| Schema contract | No field or type changes that break existing client queries — contract testing, GraphQL edition. |
A practical GraphQL test plan
- Start from the schema. Enumerate types and fields; generate at least one happy-path query per queryable field and one call per mutation.
- Assert on the envelope, not the status. Every test checks both
dataanderrors— a 200 with errors is a failure unless the test says otherwise. - Write the hostile queries. Maximum depth, wide selections, missing required arguments, wrong types, unauthorized fields.
- Load test by query shape. "The API" doesn't have one performance profile — each query shape does. Test your top five shapes under load.
- Guard the contract. Diff the schema and response shapes every build.
GraphQL testing with Flasqo
Flasqo's GraphQL module is schema-aware: it generates query and mutation tests automatically — including error-path and authorization cases — and runs them beside your REST, load and chaos suites in the same free dashboard. Point it at your GraphQL endpoint and review the generated suite.