Use spec -fh
to have Spec output its test results in nicely formatted html. Example:
spec -fh spec/models/person_spec.rb
Of course, html output on the prompt isn't really all that nice, so let's redirect the html to a browser:
spec -fh spec/models/person_spec.rb | firefox
Hm, results in a 'broken pipe'… Php to the rescue! This forum post gives us a php script which turns Spec's output into a temporary file. The script subsequently opens firefox with this file and you're presented with a great Spec report.
I have crudely adjusted the code for my own needs:
#!/usr/bin/php-cgi <?PHP $fp = fopen('php://stdin','r+'); $n = 1; while(!feof($fp)){ // read our line in from STDIN $line.= trim(fgets($fp,4096)); flush(); ++$n; } fclose($fp); if (($argc <= 3) && (!in_array('help', $argv))) { $file_tmp = 'Pipe2Browser-'.substr(md5(date("U")),14,19). (((strlen($argv[1]) < 5) && (strlen($argv[1]) > 0)) ? $argv[1] : '.html' ); if (file_exists('/tmp/pipe2browser')) if (!is_dir('/tmp/pipe2browser')) { exec('rm /tmp/pipe2browser'); } else { // remove this "else" condition if you don't want temps to autoclean... exec('ls /tmp/pipe2browser', $lsres); if ($lsres) exec('rm -r /tmp/pipe2browser/*'); } if (!file_exists('/tmp/pipe2browser')) exec('mkdir /tmp/pipe2browser'); $file_tmp = '/tmp/pipe2browser/'.$file_tmp; exec('echo "'.addslashes($line).'" > '.$file_tmp); //$browser = '/Applications/Safari.app'; $browser = 'firefox -new-window'; if ($argc == 2) { if (is_file($argv[1]) || (is_dir($argv[1]) && strpos($argv[1], '.app'))) $browser = $argv[1]; } if ($argc == 3) { if (is_file($argv[2]) || (is_dir($argv[2]) && strpos($argv[2], '.app'))) $browser = $argv[2]; } //exec('open -a '.$browser." '".$file_tmp."'"); exec($browser." '".$file_tmp."'"); } else { echo 'Error! Usage: $ pipe2browser [file_extension] [/Applications/YourBrowser.app]'; exit(1); } echo "\n"; exit(0); ?>
As the forum post says, do a sudo chmod +x pipe2browser
to get the script going (and do not forget to place it into your .scripts directory where it will be found automatically). As an aside: this script could of course easily be rewritten in Ruby (but I'm just to lazy to do that myself).
There's also a Perl oneliner (from a blog post) which does very much the same thing:
#!/usr/bin/perl -00 use File::Temp;$f=File::Temp->new;print{$f}<>;system qw{firefox -remote},"openURL(file://$f, new-tab)"
Except that the temp file is no longer available if you use the -new-window option (instead of -remote) for firefox…
In my experience, RSpec caches each class it encounters when running multiple tests. So, if you do something like:
script/spec spec/models/*_spec.rb
And these are your tests:
a_spec.rb b_spec.rb c_spec.rb
Then all classes loaded in a_spec.rb will not be reloaded for the tests in b_spec and c_spec. While this is undoubtedly great for performance, it sometimes causes trouble.
Observe this code:
describe Asset do fixtures :asset_types, :organizations, :users, :assets, :allotments, :facilities before(:each) do class Asset default_scope nil end @asset = Asset.new end ... end
This overwrites a default_scope setting in class Asset (because it causes trouble in RSpec when used in combination with Globalize2-specific default_scopes). If however, class Asset was loaded by another RSpec test (in the same test run), then you're in trouble!
Solution: put the overwrite in the very first test, as well as in the original test.