I am involved in unit testing some legacy shell scripts.
In the real world, scripts are often used to call utilities such as find
, tar
, cpio
, grep
, sed
, rsync
, date
, etc. with some rather complicated commands containing many options. Sometimes regular expressions or wildcard patterns are created and used.
example : a shell script, which is usually called by cron at regular intervals, has the task of flipping some huge directory trees from one computer to another using the rsync utility. Several types of files and directories should be excluded from the mirroring process:
#!/usr/bin/env bash ... function mirror() { ... COMMAND="rsync -aH$VERBOSE$DRY $PROGRESS $DELETE $OTHER_OPTIONS \ $EXCLUDE_OPTIONS $SOURCE_HOST:$DIRECTORY $TARGET" ... if eval $COMMAND then ... else ... fi ... } ...
As Michael Perce wrote in his famous book Effectively working with Legacy Code , a good unit test works very quickly and does not touch the network, file system or open any database.
Following Michael Peruzโs advice, the following technique should be used: dependency injection . The object to replace here is the rsync
utility.
My first idea: in my shell script, the testing environment (I use bats ) I manipulate $PATH
so that mockup rsync
found instead of the real rsync
utility. This mockup object can check the parameters and parameters of the provided command line. Similar to other utilities used in this part of the script in the test .
My past experience with real problems in this area of โโscripting was often an error caused by special characters in file or directory names, problems with quoting or encodings, missing ssh keys, incorrect permissions, etc. Such errors could avoid this unit testing technique. (I know: for some of these problems, unit testing is simply not a cure).
Another drawback is that creating a layout for a complex utility like rsync
or find
is error prone and a tedious engineering task.
I believe that the situation described above is quite common, that other people may encounter similar problems. Who has any smart ideas and would like to share them with me?