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.

Gemfile
gem 'guard' gem 'guard-phpunit2', :git => 'https://github.com/akatakritos/guard-phpunit2', :branch => 'realtime-optional'
Guardfile
# 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