You might find Test::Deep right up your alley!

On Fri, Sep 9, 2016 at 6:34 PM, Sam Kington <s...@illuminated.co.uk> wrote:

> 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