Making guard-phpunit2 Realtime
I’ve been using guard and guard-phpunit2 for unit testing PHP code at work. (Hey, at least there are tests)
One of my main difficulties with it is that it did not show output in real-time. It ships with a really nice rspec inspired result printer, but unfortunately during a run of a large test-suite you can’t see any output until the entire thing is done.
guard-phpunit2 works by shelling out to phpunit
and then parsing the subprocess’s output.
This has the unfortunate side-effect of swallowing all of phpunit’s progress
output until complete.
Real time output requires a different algorithm. Luckily,
PHPUnit provides a few different logging options.
Using --log-json file.json
will write an event log of every test to
file.json
. Guard can then pick up that file and parse it, completely
ignoring phpunit
‘s STDOUT.
I forked the project and replaced the output parsing logic with a new parser
that can process the --log-json
file.
The only other thing to do is to use system
instead of %x{ }
.
system
hooks the child process’s standard out to the parent process’s standard
out. This allows everything printed by PHPUnit to immediately appear on the
console.
%{ }
is the same as back-ticks: it eats the standard output of the child
process and returns it as a string.
I’ve got a PR put in, but the maintainer appears to be busy and hasn’t commented on it. Until its merged, you can point your Gemfile at my GitHub branch.
gem 'guard'
gem 'guard-phpunit2',
:git => 'https://github.com/akatakritos/guard-phpunit2',
:branch => 'realtime-optional'
# Add the :realtime => true option to use realtime outputting
#
guard 'PHPUnit2', :realtime => true do
watch(%r{^libraries/.+Test\.php$})
watch(%r{^libraries/es/(.+)\.php$}) { |m| "libraries/es/#{m[1]}_Test.php" }
watch(%r{^leads/(.+)\.php}) { |m| "libraries/leads/#{m[1]}_Test.php" }
end