What news from AWS re:Invent last week will have the most impact on you?
Amazon Q, an AI chatbot for explaining how AWS works.
Super-fast S3 Express storage.
New Graviton 4 processor instances.
Emily Freeman leaving AWS.
I don't use AWS, so none of this will affect me.
Software Development

End-to-End Test Troubleshooting

Using GitHub Actions, BrowserStack and Foresight to find problems quickly and save time during the debugging process.
Jan 30th, 2023 11:08am by
Featued image for: End-to-End Test Troubleshooting
Image via Pixabay.

In today’s ocean of software, what makes users choose your product over another? Is it because you fill a niche? Or is it due to great product design? Maybe it’s your marketing strategy.

All of these are important components for luring customers, but when you need to retain them, it comes down to product quality. Product quality correlates directly to the tests you run.

To maintain quality, we often implement a CI/CD pipeline and run automated tests after every build of the production code. To prove that the product meets user expectations, we also add end-to-end testing.

In this article, we’ll create GitHub workflows that we’ll then use to build the application. Next, we’ll run end-to-end tests for the application. Finally, we will apply Foresight, which offers capabilities for monitoring and troubleshooting workflow, ensuring that we can figure out problems quickly and save time during the debugging process.

Implementing the Application

Let’s build an application that enables users to manage their favorite movies. Our service will be able to create new users and authenticate them, as well as add new movies, update movies, get movie content and delete movies.

We’ll use MongoDB as the database for storing data. To make sure the service can scale, we’ll use the cloud MongoDB service in MongoDB Atlas, and we’ll create a free-tier cluster. Note that to be able to access the database from anywhere, we need to set the inbound rule for the MongoDB cluster.

You can find the full details of how this application works in this GitHub repository.

Now we’re ready to bring up our service with the following command:

node index.js

By default, the service will be brought up using port 3000. Let’s test the application to see whether our service will be able to create new users and add a new movie into the system with Postman.

After we create a movie, it seems like our application works. Now we can move to the frontend.

Building the Frontend Service

For regular users to be able to use and interact with our application, we need to create a frontend service. We’ll implement the user interface with the help of React in JavaScript. Details of the application’s frontend are available in this GitHub repository.

After implementing the UI, we can trigger the frontend by using the following command:

npm run start

For better management of the whole application, and to enable users to access the application and its API, we need a few more features.

Setting Up NGINX to Forward Requests

We will define the nginx.conf so that when users go to our web application, the requests will be forwarded to the right place for both frontend rendering and backend requests.

After setting it up, you should be able to see the movies list on the homepage.

Setting Up Ngrok for Public Address of the Application

Now we’ll set up Ngrok to create a public address for our local IP address. First, we create the ngrok.yml file for defining the port to expose, as well as our Ngrok token. And then we’re ready to expose our port for local addresses to the world.

./ngrok start all

Writing an End-to-End Test for the Application

Now that the application is up and running, we can write our end-to-end test using Jest (Node.js) with Selenium in the BrowserStack platform.

BrowserStack is a cloud solution that supports automated testing for multiple environments. For convenience, we’ll use its service for our end-to-end test, and we’ll use Selenium because it’s popular and mature. We also need a test runner. We’ll go with Jest because of its helpful features for structuring tests, and because it’s a popular choice for a Node.js testing solution.

Our sample end-to-end test is outlined in this Gist, and the full code for the test is available on GitHub.

After we’ve successfully executed the end-to-end test for our application. Let’s move on to create GitHub Action workflows for running our application’s continuous integration pipeline.

Creating a GitHub Action Workflow

To build the application and run the test for every new change automatically, we need to create GitHub Action workflows for the application. The workflows are also integrated with Foresight to make sure we can monitor our application efficiently in the future. We need three workflows for our application: one for the backend service, one for the frontend service and one for executing the end-to-end testing. Let’s dive in and create just the backend service for today. (Details of workflows for frontend service and end-to-end testing can be found in their GitHub repositories.)

Note: To keep the demonstration simple, let’s assume that we already created the permanent web domain, instead of using a randomly generated domain by ngrok.

The workflow files for the GitHub Action are in YAML format and are located in the .github directory in our application.

Pushing the updated workflow to the GitHub repository will automatically trigger a new GitHub Action for our backend workflow. The workflow is now running successfully.

Our workflow is running automatically.

When we look at the Foresight dashboard, we can see a new updated dashboard for our application workflow. By clicking on “LATEST WORKFLOW RUN,” we can see more details about recent workflow runs, such as the “Steps” that have been executed in the workflow.

Steps that have been executed in the workflow

Navigate to the “Processes” tab. Here we can see detailed information about processes, such as which process arguments have been executed.

Information about processes, such as arguments and their duration

In the “Metrics” tab, we can check how much memory or network has been used in the workflow.

Information about processes, such as arguments and their duration

With all this information from Foresight, we can easily discover why the workflow has failed or debug performance issues in the workflow.

Debugging the Failed Test Using Foresight

In real-world projects, we frequently need to update frontend code to implement new features for our application. Let’s look at what happens if, after updating the frontend code for the new feature, one of our end-to-end tests fails.

After checking the information in GitHub Action, we still do not know why the test failed. Let’s go to the Foresight landing page to find out what happened.

From Foresight’s logs, we can see that the test failed because of a mismatched title: “Mystic River” has been incorrectly rendered as “Mystic Rivera” somewhere in our application. Let’s check the GUI of the application to see how the movie titles are displayed.

We notice that all the titles have the letter “a” added to the end, which is weird. Let’s check the source code of the frontend repository.

Information about processes, such as arguments and their duration

We notice that there’s an extraneous “a” character in the title. Remove this letter and our test is successful again.

Using Foresight, we easily found and fixed the broken workflow.

Efficient Workflows

Monitoring and fixing the delivery pipeline is not a trivial task, since there are a number of steps in the deployment process and the complexity of the application tends to grow as time goes by. With Foresight’s capabilities, we are presented with carefully chosen metrics and logs so that we can quickly identify the problematic workflow, discover why it has failed and start fixing the problem.

Sign up with Foresight and try it out for yourself.

Group Created with Sketch.
TNS owner Insight Partners is an investor in: Pragma, BrowserStack, Postman.
THE NEW STACK UPDATE A newsletter digest of the week’s most important stories & analyses.