January 2014 Archives

Test Suite Organization

I've written about this before, but now I want to show some slides from my new testing class because I think it's easier to show test suite organization rather than describe it.

Years ago I wrote HTML::TokeParser::Simple, an OO interface to HTML::TokeParser. The latter is a great module, but you are typically working with a bunch of array references like this:

["S",  $tag, $attr, $attrseq, $text]
["E",  $tag, $text]
["T",  $text, $is_data]
["C",  $text]
["D",  $text]
["PI", $token0, $text]

That can be confusing and you often have to write code that is hard to immediately understand. For example, here's the code to strip all comments from an HTML document:

while (my $token = $p->get_token) {
    next if 'C' eq $token->[0];
    say $token->[-1];
}

That small snippet isn't too bad, but when you're doing complex work with HTML documents, it can become hairy. Here's how HTML::TokeParser::Simple works:

while (my $token = $p->get_token) {
    next if $token->is_comment;
    say $token->as_is; # not brilliant, but there you go
}

The test suite, however, is a bit of a problem.

My Vim setup

People keep asking for my vim setup, so I've put it on github.

Note that it's crappy, poorly documented, and does what I need it to do. I've also cleaned it up slightly to remove some older cruft. It's only there because others have asked for it and for many people, it won't be all that useful.

Testing Random Dice Rolls

I've decided to rewrite my Perl testing course from scratch and hit upon an interesting problem that is outside of the scope of the course, but is a perfect fit for this site: testing dice rolls. I have the the following function as part of a student lesson in the course:

sub roll_dice {
    my $arg_for = shift;

    my $sides = $arg_for->{sides} || 6;
    my $times = $arg_for->{times} || 1;

    # we could have also chosen to croak() or throw an exception here
    $sides = 6 if $sides < 2;
    $times = 1 if $times < 1;

    return sum( map { 1 + int rand $sides } 1 .. $times );  # fixed!
}

Rolling dice is random and it's fair to say that testing randomness is hard. Is the above correct? For the purposes of the tests, students only need to test if the expected values are in range. But what about the distribution of those values?

Update: What an irony that I had a small bug that would pass "range" tests, but not a chi-square test :)

Want to hire me, or Dave Cross or Michael Schwern?

So far our company has been growing quickly and I'm quite pleased with that. I'm doubly pleased to announce that Dave Cross and Michael Schwern have joined us as trainers and consultants. Read the announcement here.

The Simplest Exporter?

I know this package is on the CPAN, but I can't find it. I'm revising some training material for my Perl testing course and want a simpler exporter primarily so that it can fit on my slides easier. What I currently have is:

package Some::Package;
use Ovid::Exporter qw(sub1 sub2);

sub sub1 { ... }
sub sub2 { ... }

And you would use it as you would expect:

use Some::Package qw(sub1 sub2);
# or
use Some::Package ':all';

The code looks like this:

package Ovid::Exporter;

use strict;
use warnings;
use Carp ();
require Exporter;

sub import {
    my ( $class, @subs ) = @_;
    unless (@subs) {
        Carp::croak("$class requires a list of subs to import");
    }
    my $calling_package = caller;

    no strict 'refs';
    push @{"${calling_package}::ISA"} => 'Exporter';
    @{"${calling_package}::EXPORT_OK"} = @subs;
    %{"${calling_package}::EXPORT_OK"} = ( all => \@subs );
}

1;

It's dirt simple and doesn't require any work to think about or any non-core dependencies. It also fits my training needs perfectly, but I'm sure it already exists on some dusty corner of the CPAN. Where would I find it?

Ditching A Language

I can't go into the full background and a couple of details have been changed to protect the innocent, but I was chatting with a company that I'll call Acme. They faced a situation that I've seen before and usually ends badly. The code base they have looks like this:

  • Roughly a million lines of legacy spaghetti code
  • Very little use of existing libraries ("not invented here" syndrome)
  • Siloed developers
  • Hard to maintain and extend
  • Prospective developers see the code and "nope" the heck out of there

I have spoken to quite a few companies in this mess and Acme had a solution for dealing with it: they were going to rewrite the code base in another language.

Oh really?

Major Test::Class::Moose Update

Test::Class::Moose version 0.40 has been uploaded to the CPAN. Or you can get it now on github. It's a major improvement in many ways, including the fact that parallel testing is now in main branch and it works much better! Read on for the changes.

Why I Didn't Submit A Patch

Currently RT cannot talk to PAUSE, so I can't submit a bug report for this:

perl -Mutf8::all -MDateTime::Tiny -E \
    'say DateTime::Tiny->from_string("୭୮୯௦-௧௨-௩௪T௫௬:௭௮:௯౦")'
0000-01-01T00:00:00

About Ovid

user-pic Freelance Perl/Testing/Agile consultant and trainer. See http://www.allaroundtheworld.fr/ for our services. If you have a problem with Perl, we will solve it for you. And don't forget to buy my book! http://www.amazon.com/Beginning-Perl-Curtis-Poe/dp/1118013840/