Shell Script to Run PHPUnit Tests With or Without Code Coverage
At my workplace there has been a large impetus for us to fully embrace test-driven development. This, coupled with my desire to get more familiar with shellscript inspired me to modify my unit test script to be, well, more useful.
The previous one simply iterated through a folder and ran all tests in that folder one by one, something PHPUnit does by default. This became a problem when we wanted to render code coverage results because we kept overwriting the results and therefore only the last result was ever visible. Useless. Running PHPUnit whilst rendering code coverage (let's call it CC from now on, my fingers don't like the unnecessary repetition) was significantly slower (even on the beasts we use at work) therefore one of the requirements was that the script should be able to run without generating CC if the user did not want it.
So to run my function to generate code coverage, I do
./rununittests -c html
Otherwise for a normal run, I would simply run
./rununittests
USAGE
rununittests [-c clover|craph4j|html|php|text] [-d path/to/coverage/output]
-c [coverage type] Create code coverage
-d [destination] The path to save the code coverage
-h This help
-? This help
And the code
## rununittests
# The function to show the help
showHelp () {
echo ""
echo "Usage";
echo "rununittests [-c clover|craph4j|html|php|text] [-d path/to/coverage/output]";
echo "-c [coverage type] Create code coverage";
echo "-d [destination] The path to save the code coverage"
echo "-h This help"
echo "-? This help"
}
# The default destination of the coverage results
dest='temp/unittestresults'
# If option '-c' is passed, the coverage that we will generate
coverage=''
while getopts "c:d:h?" opt; do
case $opt in
c)
coverage="--coverage-$OPTARG"
continue
;;
d)
dest="$OPTARG"
continue
;;
h|\?)
showHelp
exit
;;
esac
done
if [ $coverage ];
then
phpunit $coverage $dest --verbose --bootstrap index.php unittests
exit
fi
phpunit --verbose --bootstrap index.php unittests
And a quick breakdown of what I was doing
showHelp () {
echo ""
echo "Usage";
echo "rununittests [-c clover|craph4j|html|php|text] [-d path/to/coverage/output]";
echo "-c [coverage type] Create code coverage";
echo "-d [destination] The path to save the code coverage"
echo "-h This help"
echo "-? This help"
}
All that was done here was declare a function to show the help file should we want to do so more than once.
# The default destination of the coverage results
dest='temp/unittestresults'
# If option '-c' is passed, the coverage that we will generate
coverage=''
All we do here is declare variables that we will use later. Note the absence of space around the equals sign.
while getopts "c:d:h?" opt; do
case $opt in
c)
coverage="--coverage-$OPTARG"
continue
;;
d)
dest="$OPTARG"
continue
;;
h|\?)
showHelp
exit
;;
esac
done
This part of the function is a simple switch statement
, called a case esac
statement in shell script (I believe).
while getopts "c:d:h?" opt; do
getopts
is the function that allows us to pass options to our shell script. The colon after the letter (e.g. c:
) means that we are expecting an argument after the option, which is stored in the variable $OPTARG
. This means that our possible options in this function are -c [argument]
, -d [argument]
, -h
and -?
.
if [ $coverage ];
then
phpunit $coverage $dest --verbose --bootstrap index.php unittests
exit
fi
phpunit --verbose --bootstrap index.php unittests
The last part of the script is a simple if statement, bash style. Note the space around the square brackets