Having worked with software containers in multiple projects for a couple of years now, I’ve been blown away by the advantages they can offer for software testing.
So, the main question is what are containers and what do they do? When an application traditionally runs on a system, it’s in a fight for that system’s CPU, memory and resources alongside all the other processes that are running.
However, when a container runs, it is given its own slice of CPU, memory and resources to use, freeing it up from this contention.
Another major difference is that on a traditional system, the application would be running on the system’s operating system, but containers are abstracted away from the OS and only share access to its kernel.
So, now we have a basic understanding of what containers are, let’s examine their benefits, specifically focusing on testing and quality.
Creating A Standard Environment
When a non-containerised application is created, you usually need to version control the source code and then look to deploy this code to multiple environments through its lifecycle. This might be test, pre-production, UAT or any other environments through to production. This process is fallible and can mean the application is running on completely different environments each time.
With a containerised application, you deploy the application on to an image, which is a packaged version of the entire environment and the instructions to run the application on that environment.
This image can then be version controlled and passed around the different environments meaning that a lot of the variables are removed from each environment, making it much easier to investigate any issues.
This advantage extends to running locally – as in order to test a containerised application locally you can just get the relevant image and spin it up!
This means you are running the application in the exact same environment that it is running on in production.
With standard applications when there is an issue you may need to restart the application to recover. On a normal environment this could cause knock-on effects like locked files, frozen processes, memory not released and so on.
However, with a containerised application all you need to do is stop the container and start it again. As everything within the containers is isolated from the rest of the system any potential issues that happen within the container are isolated as well.
Continuous integration pipeline
There are actually many benefits to a CI pipeline when it comes to containers, so let’s examine some of them individually.
Standard automation clients
How many times as a tester have you seen or experienced issues where you are running automated checks on one machine that don’t happen on another?
Containers can provide a solution to this by allowing you to actually containerise the client running the automation. You no longer have to worry about the client operating system, the client resources or other applications running on the client because every client will be running in the same environment!
In a normal CI pipeline, to deploy your application version to many environments, you would need to access code from some kind of repository at different stages, build that code and then attempt to deploy the artifacts.
Alternatively, you might build the application once and pass around the build artefacts which would still need to be unpacked and deployed. Which containers you can build your application once, running automation as appropriate and then package this up as an image and pass this around to different stages.
This means all you need to do it run that container on the next stage without any building or deployment. Depending on your hosting solution you may need some way to get the image to the host and run it, but doing this will almost always be simpler than deploying artefacts.
Standard deployment environments
It’s not only the application environment that can be made in to an image. As we’ve seen above the client used to run the tests can also be an image and we can also use a standard image to actually perform the steps in the CI pipeline.
A lot of CI technologies these days (such as Concourse) already do these and spin up containers to run the tasks you define. However, even with these, we can control the base image the task is run on ourselves.
Controlling these images means when we build our application we can control the software packages on the environment, any environment variables that might be hanging about and anything else we want to. This allows us to be much more confident that when we do any deployment activities they are not being affected by things outside of our control.
When an issue occurs in production with a non-containerised application, it can be difficult to determine where the issue was introduced. Ideally, we’d always aim to fix-forward with issues, but in certain companies any issues or downtime may be very costly and rolling back might be a reasonable temporary solution.
However, this can be difficult to do, especially if you have multiple applications talking to each other and external dependencies like a database.
But with a containerised application, you can simply go back to a previous image of your application and spin this up! If your application has external storage you may still have to consider these, but the rollback of the application itself is simple.
It’s also easier to find out which version you can rollback to safely, as every version of the application will have its own image so you can go to that specific image and test it locally or on any environment before making any changes to production.
Containerisation is no longer a new technology and has reached a good level of maturity meaning some of the biggest companies in the world have climbed on board. These companies (such as IBM, Microsoft, Sun etc) have handily built their own publicly available images for you to use locally.
Widely used technologies
If you need to run a particular technology locally like a database technology or an environment for a particular language, then you can just download the image and spin up a container.
Some examples I’ve used before are:
- Databases: Multiple technologies such as Oracle, Cassandra and DB2 as well as cloud technologies such as DynamoDB from AWS and No-SQL technologies such as MongoDB
- Streaming: Kafka and RabbitMQ docker images are ones I’ve used, but other streaming technologies also have public docker images.
There are many others including some great images available for CI and test- based tools, but this is just a few examples from my own usage.
Another use of publicly available images is to spin up utilities and services that you have complete control over. Rather than having to hit some physical server somewhere, you can download and use these images easily and for free.
Some examples of this I have used are:
- Wiremock: If you need to have something that runs and mocks out rest calls, there is a Wiremock image you can download and run
- FTP/SFTP: A very useful set of images for any time you need to run an FTP or SFTP server, which you can then query and interrogate to check the files being received
- SMTP: I’ve used an image called MailHog for emails before, which means you can create a container from this and have your own SMTP server to hit and retrieve the emails from – excellent for automation
- HTTP: A simple image running a http server which opens routes for requests, meaning anywhere you send out requests to an external service can be pointed here for automated checks to ensure those messages are sent correctly
- Zebra Printers: Very useful for automating checks to and from printers where you want to ensure the right data is sent out to an external printing source.
There are hundreds more of these types of images available and for me this is the biggest way that testing has been revolutionised by containerisation.
Software containers – conclusion
As I’ve shown, there are a number of advantages for testing by making use of containers. This article is not designed to persuade you to containerise your applications themselves, because that’s not always appropriate or easily achievable, however, I think I’ve shown some good benefits if you do choose that approach.
However, I would encourage you to think about other ways that containers can help you with testing – perhaps with using public images in your automation or using images in your CI.
Steven Burton, senior consultant, Infinity Works