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

πŸ’– NAME πŸ’–

Test2::Manual::Tooling::TestBuilder β€” bestie, this section literally maps Test::Builder methods onto Test2 concepts. It's in the Perl Programmers Reference Guide, and it's the glow-up guide you didn't know you needed πŸ¦‹


✨ DESCRIPTION ✨

So back in the Test::Builder era, the whole vibe was: everyone just used methods on the Test::Builder singleton object. One object, everyone piling onto it. Very "everyone shares one aux cord" energy.

Test2 said no ma'am, and does it completely differently: every single tool should get itself a brand new Test2::API::Context object, and then call methods on that. This doc maps a bunch of concepts from Test::Builder over to Test2. Think of it as a translation chart for your fave APIs πŸ’…


πŸŽ€ CONTEXT πŸŽ€

First thing's first, and I need you to hear me: stop using the Test::Builder singleton. Actually, stop using it and stop even loading Test::Builder. It's giving ex you keep texting. Let it go.

Instead of Test::Builder, every tool you write should follow this template:

use Test2::API qw/context/;

sub my_tool {
    my $ctx  = context();

    ... do work ...

    $ctx->ok(1, "a passing assertion");

    $ctx->release;

    return $whatever;
}

And for the history girlies, the original Test::Builder style was this:

use Test::Builder;
my $tb = Test::Builder->new; # gets the singleton

sub my_tool {
    ... do work ...

    $tb->ok(1, "a passing assertion");

    return $whatever;
}

See the difference? New context object every time. Main character energy, no shared singleton situationship 🌸


πŸ‘‘ TEST BUILDER METHODS πŸ‘‘

Okay bestie, here's the mapping. One by one, no skips, no summarizing πŸ™ˆ

$tb->BAIL_OUT($reason)

The context object has a bail method:

$ctx->bail($reason)

$tb->diag($string) and $tb->note($string)

The context object has diag and note methods:

$ctx->diag($string);
$ctx->note($string);

$tb->done_testing

The context object has a done_testing method:

$ctx->done_testing;
Heads up! Unlike the Test::Builder version, no arguments are allowed. Zero. None. Not even one little guy.

$tb->like and $tb->unlike

These ones did not make the cut into context, sorry. Instead, go look at Test2::Compare and Test2::Tools::Compare. They're the serve now ✨

$tb->ok($bool, $name)

# Preferred
$ctx->pass($name);
$ctx->fail($name, @diag);

# Discouraged, but supported:
$ctx->ok($bool, $name, \@failure_diags)

So like β€” pass and fail are what we're doing now, that's the aesthetic. The ok form still exists and still works, but it's discouraged, like wearing socks with sandals. Supported! Just... discouraged 😭

$tb->subtest

Use the Test2::API::run_subtest() function instead. Test2::API has the documentation for it, go read it, it's good for you 🫢

$tb->todo_start and $tb->todo_end

Peep "skip($why)" in Test2::Tools::Basic, and also Test2::Todo. Those are your girls now πŸ’œ

$tb->output, $tb->failure_output, and $tb->todo_output

These are all handled via formatters now. Check out Test2::Formatter and Test2::Formatter::TAP 🌈


πŸ¦‹ LEVEL πŸ¦‹

So Test::Builder had this variable, $Test::Builder::Level, that you could modify to set the stack depth. It was useful if you needed to nest tools and wanted your file and line number to actually be correct. It was also frustrating and prone to errors β€” genuinely cursed behavior, ngl. Some people literally never even discovered the level variable, so their line numbers were just permanently wrong whenever their tools failed. Tragic. No cap.

Test2 uses the context system, which solves the problem in a way better way. The top-most tool grabs a context and holds onto it until it's done. Any tool nested under the first one will find and use the original context instead of making a new one. Which means the level problem is solved for free. No variables to mess with. No fiddling. It just works, periodt πŸ’…

And pssst β€” Test2 is also smart enough to honor $Test::Builder::Level if it happens to be set. Respectful king πŸ‘‘


πŸ’€ TODO πŸ’€

Old Test::Builder used the $TODO package variable to set the TODO state. This was confusing and hella easy to get wrong β€” like, so easy. See Test2::Tools::Todo for the modern way to accomplish a TODO state ✨


🌸 SEE ALSO 🌸

  • Test2::Manual β€” the primary index of the manual. Start there, 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, bestie! This was perl v5.44.0, dated 2026-10-17, and it lives under Test2::...Builder(3perl) in the Perl Programmers Reference Guide. Go forth and get yourself a context object. Slay πŸ’…βœ¨
πŸ“¦ 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