All I want for Christmas is less boilerplate
Santa's elves were once again programming away. With the population growing and Christmas more popular than ever they had replaced their hammers and saws with shiny new computers and keyboards, and CPAN modules that could order presents from Amazon and eBay and even Etsy.
It was critical that everything run smoothly, or all the girls and boys of the world would be waking up on Christmas morning to find no presents to mark Santa's visit. So, naturally, the elves had tested their code very thoroughly, taking full advantage of all the CPAN has to offer.
Their t/
directory was bursting with .t
files, and every time it came to create a new test a new .t
file would be created, and the first 30 or so lines of another random .t
file would be copied over to get it started.
use Test::More;
use Test::FailWarnings;
use Test::Warn;
use Test::Exception;
use Test::Output;
use Test::MockObject;
use Test::MockModule;
use Test::File;
use Test::LongString;
use Test::JSON;
use Data::Dumper;
binmode Test::More->builder->output, ":encoding(utf8)";
binmode Test::More->builder->failure_output, ":encoding(utf8)";
binmode Test::More->builder->todo_output, ":encoding(utf8)";
One day one particular elf was doing this copy-paste manoeuvre when something came to him in a flash: "Copy pasting code is bad!", he realised, "I would never copy and paste this much code around in lib/SantasWorkshop/
so why is it ok in t/
?". And, of course, he realised that it wasn't.
Test Kits
The elf reached for the CPAN and pulled out Test::Kit, and created a shiny new module.
package SantasWorkshop::Test;
use Test::Kit;
include 'Test::More';
include 'Test::FailWarnings';
include 'Test::Warn';
include 'Test::Exception';
include 'Test::Output';
include 'Test::MockObject';
include 'Test::MockModule';
include 'Test::File';
include 'Test::LongString';
include 'Test::JSON';
include 'Data::Dumper';
binmode Test::More->builder->output, ":encoding(utf8)";
binmode Test::More->builder->failure_output, ":encoding(utf8)";
binmode Test::More->builder->todo_output, ":encoding(utf8)";
And then he simply replaced all that boilerplate in the tests with use SantasWorkshop::Test;
and he got all the testing subroutines he wanted imported in a single statement.
At this point our elf got a bit excited. He replaced ALL the boilerplate in ALL the tests!
elf@workshop:~/code$ git show ea7ebd9 --shortstat
commit ea7ebd9cf387cd63d2a4b4e2f257e69d08ba7b5e
Author: Legolas Greenleaf <legolas@santasworkshop.fi>
Date: Sat Dec 13 08:35:23 2014 +0100
Migrate ALL tests to SantasWorkshop::Test Test Kit
1322 files changed, 2325 insertions(+), 7549 deletions(-)
And would you believe that with all those lines of code deleted every test still passed, and every child around the world got their presents?
Advanced Features
When word got around to Santa he was very impressed; so much so that he wanted to give Test::Kit a go on his own projects. As he read the POD for the module he let out a jolly "ho ho ho!" when he saw a feature he thought was very nice.
package Santa::NaughtyNice::Test;
use Test::Kit;
include 'Test::More' => {
renamed => {
'ok' => 'nice',
'fail' => 'naughty',
},
};
Now he could assert in his tests that variables were nice()
, and if anything went really wrong he just needed to use naughty()
to add a 'not ok' to his test output.
What a jolly old time Santa will have writing tests now!