Wait What… GUI Testing Inside Docker Container

Hello folks, yes you read that right. It is feasible to do GUI testing of any web application in a containerized environment.
 
Usually, when it comes to GUI testing, we often start thinking of infrastructure in which we can run our tests and we start spending a lot of effort in setting up the dev-test environment. When you have a big team, these things can become more hectic.
 
Looking at the current trend of software development, many companies emphasize full- stack development skills for developers. When it comes to developers, they now also must manage this added responsibility of implementing GUI-based automated tests. And the story doesn’t end here, at present we also struggle a lot when it comes to managing dev environment (it becomes even worst when you are working on multiple projects and that too when all are on different technology stack !) and now, we also have the overhead of test environment.
 
When such a situation arises, we often go for the easiest solution that is provisioning additional VMs. With VMs, there is always a cost involved. Cost for bearing host infrastructure, the cost for procuring software needs to run and manage VMs, and much more. Moreover, after paying all the costs, you spent a lot of time in managing these VMs. OS updates, security patches, snapshots, and whatnot.
 
This is exactly what Docker helps in solving. In this article, I will show you how easy it is to set up a parallel test environment and run all your GUI-based test inside a docker container.
 
As the entire environment (dev + test) is containerized, you can easily integrate it with your CI/CD pipeline.
 
So, let’s get started.
 
Prerequisites
  • VS Code
  • Docker for Desktop
  • UltraVNC (To take the remote connection to docker container)
  • Basic knowledge of Selenium and Docker

Application walkthrough

 
I have an Angular application, which shows some data in Grid. (Just for simplicity, I opted to go with an Angular application, but this approach can be used to test web applications developed using any framework.)

I have hosted a simple JSON file to mimic working REST API. To do so, I would be using light-weight NodeJS based server for hosting static JSON files – “json-server” (https://github.com/typicode/json-server)
 
For implementing the GUI-based automated test, I will be using a very famous and proven testing framework – Selenium.
 
Directory Structure
 
 
 
Above is the very basic project setup.
  • JsonAPI  - Holds my stub for backend API
  • WebApp - Holds sample Angular web application, which I would be testing
  • SeleniumTest - Holds .NET Core MSTest project in which I would add my Selenium-based test cases 
Let’s look at each project more closely.
 

JsonAPI

 
In the JsonAPI project, I have a sample JSON file that holds some data.
 
 
 
Along with it, I also added Dockerfile. This will help us in hosting the above JSON file inside a docker container. My docker files look like below…
 
 
 
And that’s all for JsonAPI project.
 

WebApp

 
Here I have a simple Angular application, that displays some data in the table. Nothing FANCY here!!!
 
 
To get data, this app will make an HTTP call to JsonAPI project, which hosts the data.json file.
 
Key Point
 
I also added a script, “selenium-test-start” in my package.json as below.
 
 
 
Here I added –host 0.0.0.0 and –disable-host-check flag. This is very important to run an Angular app inside a docker container.
 
I added Dockerfile.debug for this web app as below. This will help in running and debugging this app inside a docker container.
 
 
 

Docker-Compose

 
Now we have our backend and frontend ready, so let’s try to run them using docker-compose so that they can communicate seamlessly.
 
My docker-compose.yml file looks like below,
 
 
 
Key Point
 
Here in my docker-compose file, I have mounted my /WebApp/src to /myapp/src folder inside the container to enable hot-reloading of Angular application when any changes are done to code.
 
Once we have this setup, we can give the below command and we should be able to see Angular app and JSON-Server app up and running inside containers 
  1.   docker-compose up --build
Now, let’s look at the .NET Core MSTest project in which I have my Selenium test written.
 

SeleniumTest

 
The first step is to add service in a docker-compose file to run Selenium Standalone- Chrome image.
 
This docker image consists of a Selenium standalone version with Chrome pre-installed.
 
We will use the debug version of this image so that we can also debug our test which would run inside a container.
 
So, let’s set up service inside the docker-compose file as below.
 
 
After giving a docker-compose up command, all three containers are up and running and I’m able to access all the applications.
 
 
The next step is to create a .NET Core – MSTest Test Project.
 
 
I added below NuGet packages to implement tests using the Selenium framework.
 
 
Now we have all the project set up done. It’s time to write some tests.
 
I have written a very simple test to test the paginator of the table. This test checks that when the user clicks on the Next button, data in the grid should get updated.
 
 
I also added Dockerfile to this project, so that I can run it inside a container later.
 
 
 

Debug

 
To debug the test, let’s first connect to WebApp container using UltraVNC software. You can download it from https://www.uvnc.com/downloads/ultravnc.html
 
Steps to connect,
  1. Launch UltraVNC viewer
  2. Enter Computer address – localhost:5900 and click “Connect”



  3. When asked for the password, enter default password which is secret
 
And now we are connected to the container as we can see below.
 
 
Now let’s debug test in VS.
 
 
And we can see that we can see the UI in UltraVNC and debug in VS at the same time.
 
Containerizing Everything
 
As we see that our tests are all fine, we can also replace our Selenium image to the non-debug version in the docker-compose file.
 
 
To host an Angular app in the container, I added one more Dockerfile as below. Here I’m doing multi-stage build and hosting Angular app inside NGINX container.
 
 
I will also update my web-app service in the docker-compose file for the Angular app as below.
 
 
Let’s add the last service in our docker-compose file, which is to run our MSTest app as well inside a container.
 
 
We need to make a small change to our remoteDriverUrl as below.
 
 
Now we have all the pieces of the puzzle at the right place and let’s run docker-compose up –build command to run tests inside a container.
 
So, we can see that all the four services ran fine as below. 
 
 
And the test also executed successfully.
 
 
We saw how simple it is to set up everything inside a dockerized environment and tests get executed flawlessly. 
Hope it was helpful and informative.
 
Cheers :)