=pod Yesterday, someone pointed me in the direction of the RSpec testing framework for Ruby: L I suggest reading the post, if only to enjoy literary constructions along the lines of: Behaviour Driven Development is an Agile development process that comprises aspects of Acceptance Test Driven Planning, Domain Driven Design and Test Driven Development. RSpec is a BDD tool aimed at TDD in the context of BDD. That sounds like something I should pay you a lot of money for! Sign me up! Anyway, here's their example for testing a "User" object's role functionality: lang:Ruby describe User do it "should be in any roles assigned to it" do user = User.new user.assign_role("assigned role") user.should be_in_role("assigned role") end it "should NOT be in any roles not assigned to it" do user = User.new user.should_not be_in_role("unassigned role") end end The idea is you get a user object, add it to a role, and see if the change sticks (and that it doesn't affect any other roles). A reasonable test, I guess. There I a few bugs here (how do we know that "assigned role" isn't accidentally persisted across user objects), but that's really not important. You can write bad tests in any language. For the sake of comparison, let's translate this directly into Perl: lang:Perl use Test::More tests => 2; # i assume RSpec needs something like this my $user = User->new; $user->assign_role('assigned role'); ok $user->is_in_role('assigned role'), 'user in assigned role'; $user = User->new; ok !$user->is_in_role('unassigned role'), 'user not in unassigned role'; The Perl code is cleaner for a variety of reasons. First, notice that the RSpec version isn't actually Ruby code. It's not any real language; it's a new one made up only for testing. Since this is eventually run by Ruby, there is some filter in effect that changes what the programmer types, C<< user.should be_in_role >> to C<< user.in_role? >> which is actually executed. This is cute when it works, but the disadvantages are numerous. Source filtering is prone to errors because modern dynamic languages have complicated syntax -- without a macro system it's nearly impossible to change program text hygienically. So it's best to just not do it. Even if you I transform the program text correctly, the result is simply not Ruby. A Ruby programmer will have to puzzle over how this works, because it's completely inconsistent with the rest of the language. Why waste mental energy puzzling over syntax? Isn't that why you left Perl for Ruby in the first place? In Perl, we just use the C function. It's a regular function that tells the test harness "pass" if the argument is true, or "fail" otherwise. It's the simplest thing that could possibly work, and therefore is not likely to cause any unexpected side-effects. There's no source filtering, and it works like everything else in Perl. Notice that the RSpec invents a new piece of syntax, the C and C "method/operator thingies", whereas C uses existing constructs as intended: C and C (read as "foo?" and "not foo?"). While both are equally clear to a speaker of English, the Perl version is clear to any Perl programmer. No English is required; no knowledge of the testing framework is required. It's how the C operator always works in Perl. Making up new syntax is, by definition, inconsistent with the rest of the language, inconsistent with how the programmer thinks, and yet another piece of added complexity the programmer has to manage. That's a lot of inconsistency and confusion just to make your tests look like English-but-not-really. Another downside of using RSpec is that the test is actually harder to use as "documentation". If you look at an arbitrary Perl module that is tested with C, you can get a good idea of how to use the module by looking at the tests. You can even cut-n-paste the test into a script and start playing immediately. With tests written in RSpec, you can't do that. The testing language isn't Ruby, so you're stuck manually "unsugaring" the test if you actually want to run it. Finally, you'll notice that the RSpec example is B. The Perl version expresses its intent in five lines of code (actual Perl, not some newly-created pseudolanguage); the RSpec version takes eleven. There's twice as much code there, for an overall decrease in readability. In conclusion, RSpec is taking testing in the wrong direction. It hurts maintainability, reduces documentation value, adds complexity, and potentially introduces subtle bugs -- all to make your tests harder to write. I will stick with good-old C-style tests for now.