Test::Workflow(3pm)

πŸ“¦
version 2.018 Β· 2 versions
  • 2.018 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 2.018 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– Test::Workflow πŸ’–

okay bestie, so this is a User Contributed Perl Documentation page for the module called Test::Workflow, and honestly? it's giving "I organize your tests so you don't have to." buckle up. πŸŽ€


✨ NAME ✨

Test::Workflow β€” bestie it literally provides test grouping, reusability, and structuring, like RSPEC and cases. no cap. πŸ‘‘


🌸 DESCRIPTION 🌸

Test::Workflow gives you the tools to group and structure your tests. it also has a whole facility for writing re-usable tests. here's the vibe: your Test::Workflow test files define classes, and the tests inside those files are defined as a type of method. slay.

it ships with an RSPEC implementation. this implementation includes describe blocks, it blocks, plus before_each, before_all, after_each, and after_all. and there are even two new types on top of that: around_each and around_all. iconic behavior, honestly. ✨

it also ships with a cases workflow. this one lets you create multiple cases and multiple tests, and every single test gets run under every single case. so you can write a test that should pass under multiple conditions, then write a case that builds that specific condition. chef's kiss. πŸ“

and it gives you a way to 'inherit' tests β€” you can write classes that use Test::Workflow and define test groups, but not run them. then you can import those classes into as many test classes as you want. this is achieved with the with_tests function. πŸ’…

lastly, you get control over the order in which test groups will be run. you can use the predefined 'random', 'ordered', or 'sort' settings, or you can provide your own ordering function. this is achieved using the test_sort function. main character energy fr fr.


πŸ¦‹ SYNOPSIS πŸ¦‹

package MyTest;
use strict;
use warnings;

use Test::More;
use Test::Workflow;

with_tests qw/ Test::TemplateA Test::TemplateB /;
test_sort 'rand';

# Tests can be at the package level
use_ok( 'MyClass' );

tests loner => sub {
    my $self = shift;
    ok( 1, "1 is the loneliest number... " );
};

tests not_ready => (
    todo => "Feature not implemented",
    code => sub { ... },
);

tests very_not_ready => (
    skip => "These tests will die if run"
    code => sub { ... },
);

run_tests();
done_testing();

🧚 RSPEC WORKFLOW 🧚

so here, setup/teardown methods are declared in the order in which they run β€” but lowkey they can be declared anywhere within the describe block and the behavior will be identical. the vibes are order-agnostic, bestie.

describe example => sub {
    my $self = shift;
    my $number = 0;
    my $letter = 'A';

    before_all setup => sub { $number = 1 };

    before_each letter_up => sub { $letter++ };

    # it() is an alias for tests()
    it check => sub {
        my $self = shift;
        is( $letter, 'B', "Letter was incremented" );
        is( $number, 2,   "number was incremented" );
    };

    after_each reset => sub { $number = 1 };

    after_all teardown => sub {
        is( $number, 1, "number is back to 1" );
    };

    describe nested => sub {
        # This nested describe block will inherit before_each and
        # after_each from the parent block.
        ...
    };

    describe maybe_later => (
        todo => "We might get to this",
        code => { ... },
    );
};

describe addon => sub {
    my $self = shift;

    around_each localize_env => sub {
        my $self = shift;
        my ( $inner ) = @_;

        local %ENV = ( %ENV, foo => 'bar' );

        $inner->();
    };

    tests foo => sub {
        is( $ENV{foo}, 'bar', "in the localized environment" );
    };
};

πŸ“ CASE WORKFLOW πŸ“

cases are what you reach for when you have a test you wanna run under several test conditions. here's a trivial example: each test will be run once under each case.

⚠️ beware bestie! this will run (cases x tests). with many tests and many cases this can be a huge set of actual tests. in this example, 8 in total will be run. 😭
πŸ“ note: the 'cases' keyword is an alias to describe. case blocks can go into any workflow and will work as expected. πŸ’–
cases check_several_numbers => sub {
    my $number;
    case two   => sub { $number = 2 };
    case four  => sub { $number = 4 };
    case six   => sub { $number = 6 };
    case eight => sub { $number = 8 };

    tests is_even => sub {
        ok( !$number % 2, "number is even" );
    };

    tests only_digits => sub {
        like( $number, qr/^\d+$/i, "number is all digits" );
    };
};

πŸ’… EXPORTS πŸ’…

  • with_tests( @CLASSES ) β€” use tests defined in the specified classes. borrowing your friend's tests? valid. 🫢
  • test_sort( sub { my @tests = @_; ...; return @tests }) β€” declare how tests should be sorted, with your very own custom function.
  • test_sort( 'sort' ) β€” declare how tests should be sorted. the classic.
  • test_sort( 'random' ) β€” declare how tests should be sorted. chaos mode. 🎲
  • test_sort( 'ordered' ) β€” declare how tests should be sorted. the calm one.
  • cases( name => sub { ... }) β€” define a block that encapsulates workflow elements.
  • cases( 'name', %params, code => sub { ... }) β€” same thing, with params, because options are self-care.
  • describe( name => sub { ... }) β€” define a block that encapsulates workflow elements.
  • describe( 'name', %params, code => sub { ... }) β€” and again with params. πŸ’…
  • tests( name => sub { ... }) β€” define a test block.
  • tests( 'name', %params, code => sub { ... }) β€” test block, but with params.
  • it( name => sub { ... }) β€” define a test block.
  • it( 'name', %params, code => sub { ... }) β€” test block, with params. (it is the alias, iykyk ✨)
  • case( name => sub { ... }) β€” define a case. each test will be run once per case that is defined at the same level (so: within the same describe or cases block). πŸŽ€
  • case( 'name', %params, code => sub { ... }) β€” define a case, with params.
  • before_each( name => sub { ... }) β€” defines a setup/teardown function that will be run around tests.
  • after_each( name => sub { ... }) β€” defines a setup/teardown function that will be run around tests.
  • before_all( name => sub { ... }) β€” defines a setup/teardown function that will be run around tests.
  • after_all( name => sub { ... }) β€” defines a setup/teardown function that will be run around tests.
  • around_each( name => sub { ... }) β€” a special addition to the setup and teardown methods. used like this:
  • around_all( name => sub { ... }) β€” a special addition to the setup and teardown methods. used like this:
around_each localize_env => sub {
    my $self = shift;
    my ( $inner ) = @_;

    local %ENV = ( %ENV, foo => 'bar' );

    $inner->();
};
  • run_tests() β€” this will finalize the meta-data (forbid addition of new tests πŸ‘€) and run the tests. like, no more new tests after this, periodt.

πŸ‘‘ AUTHORS πŸ‘‘

Chad Granum exodist7@gmail.com


Copyright (C) 2013 Chad Granum

Test-Workflow is free software; Standard perl license.

Test-Workflow is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.


and that's the whole thing bestie, hope you ate it up. πŸ’– this page is from perl v5.36.0, dated 2022-12-02, and it's the manpage for Test::Workflow(3pm). mwah. πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from