Three and a half years ago, my colleague Ovid wrote a series about organizing test suites with Test::Class. I've happily used Test::Class for years, for projects where reusability of test suites increased my confidence in the correctness of the code and reduced duplication in my work.
Test::Class
works best when you can organize the structure of
your test suite along the lines of your classes under test.
One drawback of Test::Class
I've noticed lately is that it
follows the so-called classical Perl style of object orientation, rather than
the modern style. (The primary distinction I make between classical Perl OO and
modern Perl OO is the degree of formalism in the structure of the OO system. In
other words, an OO system that doesn't encourage or at least permit the use of
roles is in no way a modern OO system.)
The problem is Test::Class
's use of function attributes:
sub test_some_predicate :Tests {
my $self = shift;
ok $self->some_method, 'some_method() should return a true value';
...
}
While it's possible to use something like Role::Basic to provide
roles of test assertions you can apply to your test classes, the amount of work
necessary to convince Test::Class
that these composed methods are
part of the assertion framework is more work than I want to do.
The problem is that, in the
absence of a well-defined Perl 5 metaobject protocol,
Test::Class
had to build its own mechanism and that mechanism
turns out not to have been reusable enough with a modern Perl object
system.
That's not the fault of the authors (who could have predicted this need to such a degree?), but it's another criticism of Perl 5's attributes mechanism which is tied too closely to Perl 5's rather ad hoc compilation model, which translated syntax into policy with too little regard for the user-defined semantics attached to extension syntax. To rephrase in another fashion, Perl 5's syntactic extension mechanisms work well enough within their compile-time lexical scope, but woe to you if you want to reuse them outside of that compile-time lexical scope. Perl's already moved well on by now.
I've used Test::Routine very productively in another project and may indeed migrate the test suite to the latter. In the mean time, the test suite (nascent though it may be after a week of work) does suffer a little bit of duplication and near duplication, ironically enough. A dose of multiple inheritance might solve the problem, but at some point a good designer has to ask whether the amount of abstraction required in a test suite is worth the result. Simplicity of debugging is a concern which outweighs many others.
Test::Class fails tests on Win32, btw.
Meaningless fail, but you will still have your module install fail, find out why, look on the test output, understand that it is insignificant, force install it, and then retry installing the original module.
Ufff.