Cleaning up the Test::Class::Moose base class

I'm quite enjoying Test::Class::Moose. It's very easy to use and it gives you such fine-grained control over your test suite and powerful reporting capabilities that it's turning out to be far more powerful than I had expected. It's actually easy enough to use for beginners, but power users will really appreciate it. There was, however, a major issue I had with it and it stems from a habit I picked up from Test::Class.

For those who are very familiar with using Test::Class (or if you've read my Test::Class tutorial), you may be used to seeing a base class that looks like this:

package My::Test::Class;
use parent 'Test::Class';

INIT { Test::Class->runtests }

sub startup  : Tests(startup)  {}
sub setup    : Tests(setup)    {}
sub teardown : Tests(teardown) {}
sub shutdown : Tests(shutdown) {}

1;

The empty test control methods are there so that a subclass knows it can always safely do this:

sub startup : Tests(startup) {
    my $test = shift;
    $test->next::method;
    # more code here
}

Those stub test methods are no longer needed with Test::Class::Moose, but until today, that INIT block was an annoying code smell that had some unfortunate side-effects. Let's make that go away.

Tags now available with Test::Class::Moose

Side note: Why did I miss that last Perl QA-Hackathon? I've attended every one since they started ... except for the last one. I missed it because the damned French government can't get around to reissuing my damned visa, despite the fact that they're legally required to. I've also had to pass on some business opportunities and a trip Romania. /me is very unhappy with France right now.

So I've finally gotten around to updating Test::Class::Moose to have tags. You can read my previous post when I explain why they're useful. You can go out to github and grab it now, or wait a bit for it to hit your favorite CPAN mirror.

The constructor is very straightforward. For the case I previously described when the network went down? Skip test methods with a network tag!

Test::Class::Moose->new(
    exclude_tags => 'network', # scalar or arrayref of tags
)->runtests;

Or maybe you want to run your Big Data and API tests, but skip deprecated methods:

Test::Class::Moose->new(
    include_tags => [qw/bigdata api/],
    exclude_tags => 'deprecated',
)->runtests;

This should solve a common issue where people want to attach metadata to their test suite but there's no clean support for it.

Unfortunately, this was implemented with Sub::Attribute. That's a fantastic module, but it's an optional dependency that some don't want. I had to use that module, though, because there's a little-known edge case where subroutine attributes won't fire if the module was loaded via "eval". I might try another swing at fixing this in the future (via require and a path in Test::Class::Moose::Load?), but for now, if you can't load Sub::Attribute, a warning will be issued and your tag filters will be ignored.

Patches welcome for improving this feature (there are many things which can be done here), but for now, this is the last major piece really needed to make this the goto module for many large test suites.

Fractal Diamond-Square Terrain Generation in Perl

The title is mostly for search engines for anyone who encounters this in the future.

I have, for no particular reason, decided to implement the fractal diamond-square terrain generation algorithm in Perl. Sometimes it's nice to just play.


    $$$$$$$$$$$$$$$$$$$$$$$####################*********************!**!!!!!!!!!!!!!
    $$$$$$$$$$$$$$$$$$$$$$#####################****************************!!!!!!!!!
    $$$$$$$$$$$$$$$$$$$$$$###########################*#*##*#*####************!!!!!!!
    ####$####$#$#$$$$$$$$$##########################################**********!!!!!!
    ################$$$$$$$$##########################################**********!!!!
    #################$$$$$$$$$##########################################**********!!
    *###############$$$$$$$$$$$#########################$##$#$$$$########**********!
    ****#*############$$#$##$##########################$$$$$$$$$$$########**********
    ********#############################################$$$$$$$$#########**********
    *************#########################################$#$##$########************
    !*!*************###################################################*************
    !!!!!!*!**********####*##*#*#######################################*************
    !!!!!!!!!!!*****************############$##########################*************
    =!!!!!!!!!!!!***************###########$$$##########################**#*#*******
    ====!!!!!!!!!!!!***********############$$$$$#############################*******
    ;=======!!=!!!!!!!**********##**#######$##############################**********
    ;;;;;;========!!!!!!!***************###############################*************
    ;;;;;;;;========!!!!!!!!*!*!**********############*##############************###
    ;;;;;;;;;;;=====!!!!!!!!!!!!!!!********#*#**************######*************#####
    :;;;;;;;;;;======!!!!!!!!!!!!!!!***************************#*#*********#########
    :::;;;;;;;;;======!!!!!!!!!!!!!!!*************************************##########
    ::::::;;;;;;=======!!!!!!!!!!!!!!!*!*******************************#############
    ~:::::;;;;;;;;=========!!=!!!!!!!!!!!!!*!***************************############
    ~~::::::;;;;;;;;=;===========!=!=!!!!!!!!!!!!!!!*********************#*#########
    ~~~~:::::::;;;;;;;;=;===============!!!!!!!!!!!!!!!*********************########
    ~~~~~~:::::::;;;;;;;;;;;;;=;==========!!!!!!!!!!!!!*!*******************########
    -~~~~~~~::::::::::;;;;;;;;;;;;;==========!=!!!!!!!!!!!!*****************########
    ----~~~~~~~::::::::::;;;;;;;;;;;;=============!!!!!!!!!***************##########
    ------~~~~~~~~:~:::::::;;;;;;;;;;;;;============!!!!!!!!**************#######$$$
    ,--------~-~~~~~~~:::::::::::;;;;;;;;;==========!!!!!!!!!***********#########$$$

Code Evolution Versus Intelligent Design

I didn't actually intend for this to be a series of posts, but hey, that's the consequence of going with the flow rather than rigidly planning everything out beforehand and it nicely mirrors the theme of:

If you have not read those, I strongly recommend that you do so before continuing on this post. Mostly the comments have been positive, but Adrian Howard has offered some interesting counter-points and some good resources for further reading. I will not say that he's wrong, but there is a different way of looking at this situation.

When Must You Test Your Code?

Recently I wrote about how to be agile without testing (if you haven't read that, you should do so before reading this). I was planning on a follow-up after some comments came in and so far the reaction was decidedly mixed. I think that's a shame because not many people seemed to focus on the punchline:

And that's really the most interesting idea of this entire post: your customer's behavior is more important than your application's behavior.

About Ovid

user-pic Have Perl; Will Travel. Freelance Perl/Testing/Agile consultant. Photo by http://www.circle23.com/. Warning: that site is not safe for work. The photographer is a good friend of mine, though, and it's appropriate to credit his work.