How to test a GraphQl API? [closed]
Asked Answered
M

2

18

I need to write a functional test suite (that will test a GraphQl API). The test suite will be in a separate repo and container from the API.

One approach I thought of would be to use a BDD framework within the test suite. The suite would run all the BDD tests after receiving a HTTP request.

I was considering using Cucumber.js as the BDD framework. I know there is npm test. I am not sure how I will execute the tests. It feels a bit awkward to use a unit testing framework in this way. Does this approach make sense?

What tooling exists to do something like this? I am open to consider various languages and tools.

Martijn answered 16/3, 2017 at 18:16 Comment(1)
I'm not experienced to give a good enough answer but this post helped me out medium.com/entria/… I've tried to implement cucumber with my implementation here is an example github.com/RedLeap/swapi-graphql-module/blob/… -- Just reiterate I'm not an experienced tester just thought I'd give my two cents rather than just leaving this unanswered. If you do have any questions please do let me know :)Graham
L
9

Karate is a relatively new web-services test-automation framework that happens to be well suited for testing GraphQL responses because of 2 specific capabilities

  • text manipulation: it is easy to in-line GraphQL queries, read them from (re-usable) files and substitute placeholders
  • JsonPath assertions: although GraphQL responses are JSON, they change dynamically depending on the request (no fixed schema) and tend to be deeply nested. Karate's native JsonPath assertions allow you to focus only on the chunks you need, and you can express expected results in short-cut JSON form, which is very readable

Here is a good example: graphql.feature with a snippet below:

# you can also read this query from a file
Given text query =
"""
{
  pokemon(name: "Pikachu") {
    id
    number
    name
    attacks {
      special {
        name
        type
        damage
      }
    }
  }
}
"""
And request { query: '#(query)' }
When method post
Then status 200

# json-path makes it easy to focus only on the parts you are interested in
# which is especially useful for graph-ql as responses tend to be heavily nested
* match $.data.pokemon.number == '025'

# the '..' wildcard is useful for traversing deeply nested parts of the json
* def attacks = get[0] response..special
* match attacks contains { name: 'Thunderbolt', type: 'Electric', damage: 55 }

For non-Java teams, Karate provides a binary executable that only requires the JRE, and Visual Studio Code is sufficient as an IDE. JavaScript programmers will especially feel at home because of how Karate embeds a JavaScript runtime and supports 'lenient' JSON (no double-quotes needed, no need to enclose JSON keys in quotes).

EDIT: here's a link to an article by a team using it in production: https://www.codemotion.com/magazine/dev-hub/web-developer/graphql-testing-with-karate/

Disclaimer: dev here.

Liggins answered 24/11, 2017 at 8:41 Comment(0)
P
0

You can just use npm test with whatever test runner you want. I am using Mocha and Chai. Jest might be a bit better since i believe its probably the most advanced test suite. You simply created tests as you would any endpoint ones.

      it('should be null when user is not logged in', async () => {
        const query = `
          query {
            user(id: "") {
              username
              email
            }
          }
        `

    const rootValue = {};
    const context = {};

    const result = await graphql(schema, query, rootValue, context);
    const { data } = result;

    expect(data.user).to.equal(null);
  });

pretty straightforward way to test it. You also run a before statement inserting the relevant user into your db. The problem with keeping a test suite separate is you will need to access the db directly. Your tests should not be reliant on other API calls as that creates unnecessary dependencies. So if a test breaks then all of a sudden the root cause is harder to figure out.

Pluvious answered 27/5, 2017 at 20:51 Comment(2)
What is graphql() in your code, is that a library function?Amphimacer
@SunilLulla import {graphql} from 'graphql'Manvell

© 2022 - 2024 — McMap. All rights reserved.