====== Test Driven Development ======
===== RSpec =====
==== Redirecting Spec's html Output to Browser ====
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 [[http://forums.macosxhints.com/showthread.php?t=48260|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
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 [[http://owl.me.uk/blog/338|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...
==== Issues When Performing Multiple Tests ====
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.