BATS (Bash Automated Testing System) allows you to have quick and easy tests in a very natural language, without the need of a lot of dependencies. BATS can also grow in complexity as per your requirement. In this section, we'll use Docker with Docker Compose to handle the build and a Makefile to tie the dependencies between the build process and the BATS testing process; this will make it easier to later integrate this process into a CI system.
To step through this recipe, you will need:
Let's start with this simple Dockerfile that will install Apache and run it after clearing the cache:
FROM debian:stable-slim LABEL name="apache" LABEL maintainer="John Doe <[email protected]>" LABEL version=1.0 RUN apt-get update -y && apt-get install -y --no-install-recommends apache2=2.4.10-10+deb8u7 && apt-get clean && rm -rf /var/lib/apt/lists/* EXPOSE 80 ENTRYPOINT ["/usr/sbin/apache2ctl"] CMD ["-D", "FOREGROUND"]
For convenience, let's create a docker-compose.yml
file so the image can be built and run easily:
version: '2' services: http: build: . image: demo-httpd ports: - "80:80"
This way, running docker-compose up
will also build the image if absent. Alternatively, to just build the image, use this code:
$ docker-compose build
We'll now test two of the main actions this image is supposed to do:
Start by creating a test
folder at the root of our repository that will host the BATS tests:
$ mkdir test
Our first test is to verify that the installed version of Apache is 2.4.10
, as required. How would we do it manually? We'd probably just execute the following and check the output:
$ apache2ctl -v Server version: Apache/2.4.10 (Debian)
This translates in Docker with our image in the following command (-v
being the command (CMD
) for the apache2ctl
ENTRYPOINT
instruction):
$ docker run --rm demo-httpd:latest -v Server version: Apache/2.4.10 (Debian)
Basically, now we just have to run grep
for the correct version:
$ docker run --rm demo-httpd:latest -v | grep 2.4.10 Server version: Apache/2.4.10 (Debian)
If grep
is successful, it returns 0
:
$ echo $? 0
A simple BATS test for a command return code looks like this:
@test "test title" { run <some command> [ $status -eq 0 ] }
We now have everything we need to write our first BATS test in test/httpd.bats
:
@test "Apache version is correct" { run docker run --rm demo-httpd:latest -v | grep 2.4.10 [ $status -eq 0 ] }
To execute our test, let's launch BATS with the folder containing the tests as arguments:
$ bats test Apache version is correct 1 test, 0 failures
Good! We're now assured that the correct Apache version is installed.
Let's ensure the APT cache is cleaned after we build the image so we don't waste precious space. Deleting the APT lists means the /var/lib/apt/lists
folder will become empty, so if you count the files in this folder after this, it should return 0
:
$ ls -1 /var/lib/apt/lists | wc -l
However, we cannot just send this command to the container like we did for the Apache version; the entry point is apache2ctl
, and it needs to be overridden by sh
on the docker run
command line. Here's the apt.bats
test file, executing the shell command instead of apache2ctl
, expecting a successful execution and an output of 0
:
@test "apt lists are empty" { run docker run --rm --entrypoint="/bin/sh" demo-httpd:latest -c "ls -1 /var/lib/apt/lists | wc -l" [ $status -eq 0 ] [ "$output" = "0" ] }
Execute the BATS tests:
$ bats test apt lists are empty Apache version is correct 2 tests, 0 failures
Now this whole process might be a bit tedious in CI, with some additional steps needed before the testing is done (the image needs to be built and made available before it is tested, for example). Let's create a Makefile
that will take care of the prerequisites for us:
test: bats bats: build bats test build: docker-compose build
Now when you execute the make test
command, it will launch the bats
suite, which itself depends on building the image by docker-compose
—a much simpler command to integrate in the CI system of your choice:
$ make test docker-compose build Building http Step 1 : FROM debian:stable-slim ---> d2103c196fde [...] Successfully built 1c4f46316f19 bats test . apt lists are empty . Apache version is correct 2 tests, 0 failures
18.221.35.58