As a developer you must have heard a lot about tests. Tests help to avoid a lot of bugs and edge cases that otherwise you would never thought of.
There are four types of tests to conduct:
- Unit Tests
- Integration tests
- E2E tests
- System tests
This article will focus on GraphQL E2E tests. E2E tests are conducted by a robot, that is mimicking user's interactions with the app. In my React Native application, I use Detox for testing selected user paths. Detox is a library that lets us prepare Gray Box tests.
What is Gray Box testing?
Let’s say it’s a compromise between Black Box and White Box testing. Black Box tests are conducted by a person who has no knowledge about software (i.e. manual tests). White Box tests do the opposite. They are mostly done by machines, which have all the knowledge about app structure (i.e. unit tests). E2E tests are done from the user’s point of view and not from the engineer’s perspective, however, the tester still has some idea about code. It makes E2E a good addition to your test suite.
Prepare your GraphQL server
This article https://blog.swmansion.com/detox-your-graphql-74b58dca3221 helped me a lot with the initial setup of a GraphQL server. However, I found out that it could be explained better, especially for a less experienced frontend developer.
Download your GraphQL schema
We need introspected schema to run our server. There are some ways to do this, but I managed to download it with graphql command-line interface.
- install graphql-cli via NPM
npm install -g graphql-cli
- Setup your .graphqlconfig file.
You will be asked about your api endpoint. For me it was an url to locally running API server - http://localhost:5000/graphql
This is how the config looks:
Download the schema from the server
Get introspected schema
- Get a readable schema for future mocking
graphql get-schema --output schema.graphql
After downloading the introspected schema in json, you need to flatten query results by removing the data attribute from the root of file. The required result is under data attribute.
Prepare local server
I used the code from the article mentioned above. It was the main source for creating my mocks, I just changed it a little bit to make it work for me.
Mock your data
Let’s move on to mocking. In the app, I have all the data downloaded with graphql. Unfortunately, I cannot test creation of bookings, since users (students) are not allowed to do this. The only way to perform the test is to mock the data.
Here is a simplified version of the schema. Booking is the query for a single object and BookingConnectionWithCounts is for downloading a list of Bookings (the count is used for pagination in the web application).
In order to show data, we need to mock both types - one for the list and another for details.
You must mock all scalars from your schema. You can do it globally, but keep in mind that all scalars will have the same value. For me, I wanted my booking's dates to be varied because I need to show the time range. I’m using readable scheme for mocking.
Beware of warnings. If they overlay the component that you intended for detox to click, it can expand the warning instead and your test will fail. Mock everything that is required.
When all is done, we can start testing. My tests are pretty simple:
- Display bookings - checks the presence of booking in the list
- Show booking details - enters into a booking details and checks whether the Booking has English lessons defined
- Check bookings history - checks if bookings are rendered in history
Tests done by a machine: https://youtu.be/sLzNArDey3c
If you need help with your development, contact us.