The First Test I Always Write
Nothing fancy, I just find myself copying this test into t/ directory of every new project so I thought others might find it useful, too.
Basically, it just runs Test::More's use_ok()
on every file in the package's blib/lib directory to ensure that everything is building okay.
file: 000use.t
use Test::More; use File::Find;
my @classes = ();
my $root = 'blib/lib';
File::Find::find(
sub {
return unless $_ =~ /.pm$/;
my $path = $File::Find::name;
$path =~ s|^$root/||;
$path =~ s|.pm$||;
$path =~ s|/|::|g;
push @classes, $path;
},
$root
);ok( scalar( @classes ) > 0 );
foreach my $class ( @classes ) {
use_ok( $class );
}done_testing( scalar( @classes ) + 1 );
What's the first test you always write?
I don't even write that test. I let Dist::Zilla::Plugin::CompileTests do that for me. Along with ::ExtraTests and ::PodSyntaxTests. :)
Ooo! I Hadn't seen CompileTests before. I should really check for new dzil plugins more often. :-)
Same here, I let Dist::Zilla handle everything generic, tests among other things. So you can concentrate on writing useful tests, targeted at your application features.
Me three. In addition to letting tools generate tests that can be automated (compile tests, pod coverage, pod syntax, dist completeness, etc), in general I try to avoid writing tests that are too, how should I say, "low level". I see people doing things like:
my $obj = Foo->new;
ok($obj, "Foo object creation succeeds");
is($obj->isa, "Foo", "obj is instance of Foo");
Why would you even need to test that? Well, okay, if you're writing something like Moose, perhaps.
Just test your routines with real and edge inputs.
I also write tests to ensure everything compiles, and I bail out if they don't. That way I don't have to get a bunch of failures from every test in the test suite.
To answer Steven, I do those low level tests because I want to know exactly what's failing and catch failures as soon as possible. It makes finding the real problem much easier. I started doing it that way out of necessity rather than philosophy.
For the dzil people, your answer is effectively "but it works for me!" :)
There are a couple of reasons to do that sort of very low-level testing.
First, debugging is a process of elimination. If something isn't working as expected, you factor out the things that it couldn't be as a way of narrowing your search for what's actually wrong. By rigorously testing even the things that *seem* like they could never go wrong you are unambiguously removing those cases from your bug hunts.
Secondly, it's often a matter of iterative development. Let's say I want to add an attribute that contains an object, for example. First, I might test if the current object can() do the accessor methods for that attribute. It can't so I add the attributes and set up the appropriate accessors. Now that test passes. I used a builder to create that object instance if I didn't explicitly pass one during construction so I test that the object returned at least belongs to the right class. It does, and I know that for certain because there's an explicit test for it. And so on and so on.