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.