Having briefly explained what a test is we can come to an inevitable conclusion that having only a single test is never enough. We usually write a lot of them and it is useful to group them.
Assuming that the tests we are using conform to the contract of returning proper exit statuses, the whole group can technically be treated like a single test.
Let’s put them inside a tests.sh
script:
test -f file-a.txt
test -f file-b.txt
test -f file-c.txt
Now, (I assume that the script is an executable file) let’s run it:
./tests.sh
echo $?
# returns: 1
All is well. The required files do not exist, so the test is failing.
Create the files one by one and run the test each time:
touch file-a.txt
./tests.sh
echo $?
# returns: 1
touch file-b.txt
./tests.sh
echo $?
# returns: 1
touch file-c.txt
./tests.sh
echo $?
# returns: 0
All is well again. The test passes.
Now, let’s make sure the test is solid. Delete the first file and run the test again.
rm file-a.txt
./tests.sh
echo $?
# returns: 0
Wait, what? The test returns 0
? It should fail!
The thing is that when we put some commands into a script, by default, only the last one’s return status is returned by the script itself.
To ensure that the script will exit when a command within that script exits with a non-zero status, we use the set
bash builtin with the -e
option.
Put #!/bin/bash
(just to make sure we will be running Bash) on the first line and set -e
on the second line of the test script and run it yet again.
Now the test fails as it should.
Run a series of tests to ensure all relevant situations are being checked.
rm file-?.txt
./tests.sh
echo $? # should return 1
touch file-a.txt
touch file-b.txt
touch file-c.txt
./tests.sh
echo $? # should return 0
rm file-a.txt
./tests.sh
echo $? # should return 1
touch file-a.txt
rm file-b.txt
./tests.sh
echo $? # should return 1
touch file-b.txt
rm file-c.txt
./tests.sh
echo $? # should return 1
This shows the general idea behind testing.
I have been purposefully avoiding using the terms test cases
and test suites
as they are usually more abstract concepts I do not wish to get into here.