Simplifying imports (mainly in tests)

During test writing often I find myself having to use a lot of modules and setting up various things that should be common for all of my tests in a given project. In some examples it may get ugly and I really don't like having a ~30 lines long setup in every single test file of mine. After some experimenting, I came up with a quick-and-dirty solution. I create a module in my 't' directory (let's say t/lib/Test/MyApp.pm) and put everything I need into it's import sub:


package Test::MyApp;

sub import {
use v5.16;
use strict;
use warnings;

use MyApp;
use Dancer2;
use Dancer2::Test;
#some test-specific database settings; 'set' is exported by Dancer2
BEGIN{
set plugins => {
DBIC => {
default => {
schema_class => 'MyApp::DB',
dsn => "dbi:mysql:myapp_test",
user => 'user',
pass => 'pass',
options => {
on_connect_do => "set names utf8;",
quote_char => '`',
name_sep => '.',
mysql_enable_utf8 => 1,
RaiseError => 1,
},
},
}
};
}
use Dancer2::Plugin::DBIC qw/rset schema/;
use Test::Most;

#and some standard symbol-table export to main
{
no strict 'refs';

my $caller = caller;

while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
next if $name eq 'BEGIN';
next if $name eq 'import';
next unless *{$symbol}{CODE};

my $imported = $caller . '::' . $name;
*{ $imported } = \*{ $symbol };
}
}

}

"this is false";

After this, if I import Test::Myapp in my test, I will have all the modules imported and all the symbols I need exported (Dancer2 specific keywords, 'schema', 'rset'). Instead of ~20+ lines, I have only one.

Do you perhaps know of a better solution?

2 Comments

I think you'll find that this doesn't switch on strict, warnings, or 5.16 features in your *.t files.

If you want to combine several imports into one, take a look at Syntax::Collector, and/or Import::Into.

There's also Test::Kit for this.

Leave a comment

About Davs

user-pic About my journey with Perl, PerlDancer2, DBIx::Class and testing.