Skip to content

Instantly share code, notes, and snippets.

@bksunday
Last active December 14, 2017 10:01
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bksunday/6922149 to your computer and use it in GitHub Desktop.
Save bksunday/6922149 to your computer and use it in GitHub Desktop.
When using phpunit and logging output using TAP (from command line but easier from phpunit xml configuration), this script will re-run phpunit with only Wailed tests from last test.
#!/bin/bash
# parses a tap log file from phpunit to find failed tests
#
# This assumes you setup a phpunit.xml (or .dist.xml) so simply add something like the following under <phpunit>
# <logging>
# <log type="tap" target="/tmp/.projectname-phpunit-test-log.tap" />
# </logging>
#
# tap is used instead of json and xml because these log files get big
# and needs to be loaded completely before parsing into it to find failed tests
# and for tap we can simply read the file line by line to find those starting with "not ok"
#
# if you don't have a phpunit xml configuration you'll have to adapt this script
#
# this script assumes it is placed in the root of your project
# don't forget to set it as executable (chmod +x ./test-run-failed)
# and when running it from this root dir, use (./test-run-failed)
# adjust those to your liking
xmlconfig="phpunit.xml"
xmldir="app/"
php_cli="/usr/bin/php"
# these 2 lines works on linux, should work on mac and for windows users I don't know (and don't care)
script=$(readlink /proc/$$/fd/255)
scriptdir=$(dirname $script)"/"
# read log file location
phpunit_tap_log=$($php_cli -r '
$xml = simplexml_load_file("'${scriptdir}${xmldir}${xmlconfig}'");
if(@$xml->logging[0]->log[0]["type"] == "tap" && ($logfile = @$xml->logging[0]->log[0]["target"])) {
echo $logfile;
return 0;
} else {
return 1;
};
')
# exit if we could not find it
if [ $? -ne 0 ]; then
echo "Could not find tap log file destination in $xmldir/$xmlconfig";
exit 1
fi
# check if that log file exists right now
if [ ! -e $phpunit_tap_log ]; then
echo "Logfile not found. Run the full test suite";
exit 1
fi
# get failed tests
failed_tests=$($php_cli -r '
$failed = array();
$handle = fopen("'$phpunit_tap_log'", "r");
if(!$handle) {
return 1;
}
while(false !== ($line = fgets($handle))) {
if(substr($line, 0, 6) == "not ok") {
$class_and_method = substr($line, strrpos($line, " ")+1);
$class = substr($class_and_method, 0, strpos($class_and_method, "::"));
$failed[str_replace("\\", "\\\\", $class)] = true;
}
}
if(!$failed) {
return 1;
}
echo implode("|", array_filter(array_keys($failed)));
return 0;
')
# exit if there was an error
if [ $? -ne 0 ]; then
echo "Could not extract failed tests from $phpunit_tap_log";
exit 1
fi
# exit if no failed tests
if [ "$failed_tests" = "" ]; then
echo "No failed tests in $phpunit_tap_log";
exit 1
fi
# run filtering failed tests
phpunit -c ${scriptdir}${xmldir} --filter "'${failed_tests}'"
exit $?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment