Hi,
At $WORK we have an extensive test suite that we’ve built up over the years,
with loads of convenience methods for calling e.g. Dancer endpoints and
checking returned data structures against what we expect. One of our dev team
recently left for pastures new, and would like to carry on using these tools.
How should I best extract this functionality into a proper CPAN distribution
(ideally using Test2)?
At its most elaborate, our current test code lets you say e.g.
# Assume $self->state('location_id') has been set previously
$self->test(
title => 'Create a properly megalithic structure',
call => [
POST => '/location/:location_id/build',
{
author => 'Wally Wallington',
structures => [
{
type => 'dolmen',
material => 'concrete',
}
]
}
],
expect => {
http_code => HTTP_CREATED,
sql_count => 12,
data => {
location_id => $self->state('location_id'),
build_id => qr{^ (?<build_id> BUILD \d+ ) $}x,
built => $self->true,
author => $self->meh, # It's OK if they call him Idiot.
structures => [
{
_hashref_contains => {
structure_id => qr{^ (?<structure_id> STRUCT \d+ ) $}x,
type => 'dolmen',
material => 'concrete',
# There's probably stuff about where the dolmen
# was erected but we ignore that for the purpose
# of this test.
}
}
]
}
}
);
# $self->state('build_id') got set by the named capture in the regex above.
$self->test(
title => 'Turn it to gold because lol',
call => [
PATCH =>
'/location/:location_id/build/:build_id/structure/:structure_id',
{ material => 'gold' }
],
expect => {
# The same as saying data => { _hashref_contains => { material =>
'gold' } }
data_contains => {
material => 'gold'
}
}
);
And if anything doesn’t quite match, it tries to show you what did and didn’t
match.
The stuff in call gets passed to e.g. Dancer::Test::dancer_response or treated
as a method call, depending on the invocation. As we share a common process
with the code being called and tested, we can also monitor the database calls
being made via DBIx::Class, and there’s some fiendish code for tracking,
diagnosing and correcting test errors regarding the number of distinct database
queries being made.
These are all nice-to-haves rather than something that’s inherent to the design
of this testing code. What’s really useful, and what my ex-colleague is
hankering after, is a couple of things:
(A) To say, flexibly, “I want a data structure that looks like this”, and to be
able to say (1) this field must look exactly like this, (2) this field should
look like this, and remember it, (3) this field should exist, but I don’t care
what its value is, and (4) there might be additional fields but I don’t care
about them for the purpose of this test.
(B) To maintain a collection of placeholders that can be updated by tests and
used by subsequent tests.
I haven’t looked recently at the Test:: infrastructure, so for all I know we
may have replicated functionality that we’d missed a few years ago when we
started coding.
But if this functionality is new and useful, how should I implement it?
Sam
--
Website: http://www.illuminated.co.uk/