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/

Reply via email to