When writing unit tests, it’s often useful to know the code coverage you’ve achieved to see what proportion of your code you’re exercising. Typically you have to commit your code to version control, so your CI server can pull in your updates and produce coverage reports. This means you sometimes commit incomplete tests, where you might forget to test failure branches (throwing exceptions for example).

What’s needed is a way to produce code coverage reports from PHPUnit from the command line. Just a summary would be useful. You’ll need XDebug installed for code coverage reports.
This script was inspired by Ben Downling‘s script from 2010. Unfortunately Ben’s implementation no longer works as PHPUnit has deprecated the --log-metrics switch.
Like a lemming, I chose to implement this in bash script, a language I’m not overly familiar with … if I’d used PHP to do this, it would have been cross platform!
Update: My colleague Neel stumbled across this post and generously re-wrote the core of this bash script into several PHP classes. The classes are available in one of his github projects.
I’ve done it now though, so here’s a bash script to parse PHPUnit’s XML code coverage file and provide a percentage of the statements covered:
#!/bin/bash
COVERAGE=""
METRICS="/tmp/phpunit-metrics.xml"
if [ "$1" == "--coverage" ]
then
COVERAGE="--coverage-clover $METRICS"
shift
fi
phpunit $COVERAGE $@
# exit with PHPUnit's return code
if [ $? -ne 0 ]
then
exit $?
fi
if [ "$COVERAGE" != "" ]
then
echo "====================== Code Coverage Summary ====================="
FILTER_LINES="/<class/ { print \$2 } /<metrics method/ { print \$4,\$5 }"
JOIN_LINES="\$!N;s/\n/ /"
TRANSFORM="s/name=\"\([A-Za-z_]*\)\" statements=\"\([0-9]*\)\" coveredstatements=\"\([0-9]*\)\"/\1\t\2\t\3/"
RESULTS=$(cat "$METRICS" | awk "$FILTER_LINES" | sed "$JOIN_LINES" | sed "$TRANSFORM" | tr '\t' '|')
(for line in $RESULTS; do
CLASS=`echo "$line" | cut -d '|' -f1`;
STATEMENTS=`echo "$line" | cut -d '|' -f2`;
COVERED=`echo "$line" | cut -d '|' -f3`;
COVERAGE=0
if [[ "$STATEMENTS" > "0" && "$COVERED" > "0" ]]
then
COVERAGE=$(echo | awk "{print $COVERED * 100 / $STATEMENTS}")
fi
echo "$CLASS $COVERAGE" | awk '{printf "%-60s %.2f%\n", $1, $2}'
done) | sort -nr --key=2
rm "$METRICS"
fi
Assuming you’ve configured PHPUnit, and saved this to run_tests you can run your test suite with this script like so:
$ run_tests --coverage PHPUnit 3.5.14 by Sebastian Bergmann. . Time: 0 seconds, Memory: 5.25Mb OK (1 test, 1 assertion) Writing code coverage data to XML file, this may take a moment. ====================== Code Coverage Summary ====================== MyClass 89.73%
Enjoy!
Tweet
comments
No comments for this post.