TEST2::MANUAL::TOOLING::NESTING(3perl)

✨ NAME ✨

Test2::Manual::Tooling::Nesting β€” the tutorial for using other tools inside your own, bestie πŸ’… (it lives in the 3perl section of the Perl Programmers Reference Guide, if you were wondering where to find it).


🌸 DESCRIPTION 🌸

okay so picture this: you keep writing the same test pattern over and over and over again 😭 and at some point your brain goes "girl, just wrap that in a function." Which is a genuinely great instinct! Encapsulate the logic in a new test function that calls several tools together. Sounds easy enough, right?

...but it can cause headaches if you don't do it correctly πŸ™ˆ and we are NOT about that life.


πŸ’– NAIVE WAY πŸ’–

so let's say you find yourself writing the exact same test pattern over and over for multiple objects, like:

my $obj1 = $class1->new;
is($obj1->foo, 'foo', "got foo");
is($obj1->bar, 'bar', "got bar");

my $obj2 = $class1->new;
is($obj2->foo, 'foo', "got foo");
is($obj2->bar, 'bar', "got bar");

... 10x more times for classes 2-12

and the naive way to fix this is to write a check_class() function like this:

sub check_class {
    my $class = shift;
    my $obj = $class->new;
    is($obj->foo, 'foo', "got foo");
    is($obj->bar, 'bar', "got bar");
}

check_class($class1);
check_class($class2);
check_class($class3);
...

and like... this will appear to work fine πŸ‘‘ you might not notice any problems at all, so long as all the tests are passing. And that's the trap, bestie.

πŸ’€ WHAT'S WRONG WITH IT? πŸ’€

the problems with the naive approach become painfully obvious the second things start to fail 😭

the diagnostics that tell you what file and line the failure occurred on will be wrong. The failure will be reported to the line inside check_class, not to the line where check_class() was called. And that's a problem because it leaves you with literally no idea which class is failing. Not the vibe. Not the vibe at all.

🫢 HOW TO FIX IT 🫢

luckily this is extremely easy to fix. You need to acquire a context object at the start of your function, and release it at the end... yes it is that simple, no cap ✨

use Test2::API qw/context/;

sub check_class {
    my $class = shift;

    my $ctx = context();

    my $obj = $class->new;
    is($obj->foo, 'foo', "got foo");
    is($obj->bar, 'bar', "got bar");

    $ctx->release;
}

see? easy. With these 2 additional lines we now have proper file+line reporting πŸ’… The nested tools will find the context we acquired here, and know to use its file and line numbers. iconic behavior, honestly.

⚠️ THE OLD WAY (DO NOT DO THIS ANYMORE) ⚠️

back in the day, with Test::Builder, there was a global variable called $Test::Builder::Level which helped solve this problem:

sub check_class {
    my $class = shift;

    local $Test::Builder::Level = $Test::Builder::Level + 1;

    my $obj = $class->new;
    is($obj->foo, 'foo', "got foo");
    is($obj->bar, 'bar', "got bar");
}

this variable worked well enough (and will still work) but it was not very discoverable 🫠 Another problem with this variable is that it becomes cumbersome if you have a more deeply nested code structure calling the nested tools β€” you might need to count stack frames, and hope they never change due to a third party module 😭 The context solution has no such caveats. periodt.


🌈 SEE ALSO 🌈

  • Test2::Manual β€” the primary index of the manual. start here if you're lost, bestie πŸ’œ

πŸ”₯ SOURCE πŸ”₯

the source code repository for Test2-Manual can be found at https://github.com/Test-More/test-more/ ⭐


πŸ‘‘ MAINTAINERS πŸ‘‘

Chad Granum <exodist@cpan.org>


πŸ¦‹ AUTHORS πŸ¦‹

Chad Granum <exodist@cpan.org>


Copyright Chad Granum <exodist@cpan.org>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://dev.perl.org/licenses/


and that's the whole page, babe πŸŽ€ this was perl v5.44.0, dated 2026-10-17, and the manual name is Test2::...Nesting(3perl) β€” go forth and nest your tools responsibly 🧚✨

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms