Running end-to-end tests with GitHub Actions

Warren Day
tomorrowapp
Published in
3 min readJul 24, 2020

I always liked the idea of GitHub actions because it means less third-party dependencies on your CI/CD flow. The UI, however, is somewhat lacking compared to other providers such as Circle CI, but this is something improving over time.

Here I’ll be using Cypress to test the full end-to-end flow of a web app connected to a mocked GraphQL API. The fact the API is GraphQL makes local stubbing with Cypress difficult, due to all requests going to the same endpoint. I feel mocking the API is, therefore, the best way to go.

I’ll be focusing purely on GitHub actions rather than the configuration of the application itself.

Keeping everything together

First off I'm using a monorepo. This is important because it means both my client and API can be accessed from the same workflow. This improves the resilience of your tests because changes across each piece of your infrastructure are tested together. This compared to testing the client against a staging endpoint where the contract between the client and API could be misaligned.

Overview of GitHub Actions

At the top level, you will be running a workflow. These are made up of a series of steps; for example, you may have a workflow made up of three steps:

  1. Checkout our code
  2. Setup Node.js
  3. Build and test your app

This workflow could be called “Test App”. The workflow is defined using .yml files and should be saved at the root of your monorepo under the directly .github/workflow/test-app.yml

Here we have an example .yml file for the workflow.

Under the steps section, you can see the three steps we mentioned earlier.

You can also see the uses key here for some steps. This is the actual actions part of GitHub actions. They are pre-written units of code which can be used in any step. An example might be, deploying to AWS, compressing images, or in this case, checking out our code and setting up Node.

-

Running an end-to-end test

So now let’s see how we can use both our app and our API together to run our end-to-end tests. As mentioned earlier it’s important to have a monorepo. This way we can change the directory to run certain steps in the background.

To run a task in the background is simple, just end the command with an ampersand &

For example, I could run my mock API with yarn mock & and the workflow would carry on happily with the API now running in your container.

To do this in GitHub actions we could add a new step to the workflow. Notice how you can also add environment variables for specific steps.

The final workflow running the API and an end-to-end test would look like the following:

Here you can see we have the additional step to run our API. We then move onto our client step in order to build and test the client. But the API continues to run. We then launch our client using yarn start & to have this also running in the background.

Now when we run cypress withyarn cypress:run there will be a running client and API to access.

With this, we now have a finished workflow running an end-to-end test.

--

--