The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Test::Stream - Experimental successor to Test::More and Test::Builder.

EXPERIMENTAL CODE WARNING

This is an experimental release! Test-Stream, and all its components are still in an experimental phase. This dist has been released to cpan in order to allow testers and early adopters the chance to write experimental new tools with it, or to add experimental support for it into old tools.

PLEASE DO NOT COMPLETELY CONVERT OLD TOOLS YET. This experimental release is very likely to see a lot of code churn. API's may break at any time. Test-Stream should NOT be depended on by any toolchain level tools until the experimental phase is over.

***READ THIS FIRST***

This is not a drop-in replacement for Test::More.

Adoption of Test::Stream instead of continuing to use Test::More is a choice. Liberty has been taken to make significant API changes. Replacing use Test::More; with use Test::Stream; will not work for more than the most trivial of test files.

See Test::Stream::Manual::FromTestBuilder if you are coming from Test::More or Test::Simple and want a quick translation.

MANUAL

TODO: Manual

DESCRIPTION

This is the primary interface for loading Test::Stream based tools. This module is responsible for loading bundles and plugins for the tools you want. Test::Stream::Bundle::V1 is the suggested bundle for those just starting out.

SYNOPSIS

    use Test::Stream -V1;

    ok(1, "This is a pass");
    ok(0, "This is a fail");

    is("x", "x", "These strings are the same");
    is($A, $B, "These 2 structures match exactly");

    like('x', qr/x/, "This string matches this pattern");
    like($A, $B, "These structures match where it counts");

    done_testing;

IMPORTANT NOTE

use Test::Stream; will fail. You MUST specify at least 1 bundle or plugin. If you do not specify any then none would be imported and that is obviously not what you want. If you are new to Test::Stream then you should probably start with the '-V1' argument, which loads Test::Stream::Bundle::V1. The V1 bundle provides the most commonly needed tools.

WHY NOT MAKE A DEFAULT BUNDLE OR SET OF PLUGINS?

Future Proofing. If we decide in the future that a specific plugin or tool is harmful we would like to be able to remove it. Making a tool part of the default set will effectively make it unremovable as doing so would break compatability. To solve this problem we have the 'Core#' bundle system.

'V1' is the first bundle, and the recommended one for now. If the future tells us that parts of 'V1' are harmful, or that we need more than what is currently provided, we can release 'V2'. 'V1' will not be changed in a backwords incompatible way, so nothing breaks, but everyone else can move on and start using 'V2' in new code.

The number following the 'V' prefix should correspond to a major version number. This means that 'V1' is provided with Test::Stream 1.X. V2 will prompt a 2.X release and so on.

PLUGINS AND BUNDLES

Test::Stream tools should be created as plugins. This is not enforced, nothing prevents you from writing Test::Stream tools that are not plugins. However writing your tool as a plugin will help your module to play well with other tools. Writing a plugin also makes it easier for you to create private or public bundles that reduce your boilerplate.

Bundles are very simple. At its core a bundle is simply a list of other bundles, plugins, and arguments to those plugins. Much like hash declaration a 'last wins' approach is used; if you load 2 bundles that share a plugin with different arguments, the last set of arguments wins.

Plugins and bundles can be distinguished easily:

    use Test::Stream(
        '-V1',                          # Bundle ('-')
        ':Project',                     # Project specific bundle (':')
        'MyPlugin',                     # Plugin name (no prefix)
        '+Fully::Qualified::Plugin',    # (Plugin in unusual path)
        'SomePlugin' => ['arg1', ...],  # (Plugin with args)
        '!UnwantedPlugin',              # Do not load this plugin
        'WantEverything' => '*',        # Load the plugin with all options
        'option' => ...,                # Option to the loader (Test::Stream)
    );

Explanation:

'-V1',

The - prefix indicates that the specified item is a bundle. Bundles live in the Test::Stream::Bundle:: namespace. Each bundle is an independant module. You can specify any number of bundles, or none at all.

':Project'

The ':' prefix indicates we are loading a project specific bundle, which means the module must be located in t/lib/, lib/, or the paths provided in the TS_LB_PATH environment variable. In the case of ':Project' it will look for Test/Stream/Bundle/Project.pm in TS_LB_PATH, t/lib/, then lib/.

This is a good way to create bundles useful to your project, but not really worth putting on CPAN.

'MyPlugin'

Arguments without a prefix are considered to be plugin names. Plugins are assumed to be in Test::Stream::Plugin::, which is prefixed automatically for you.

'+Fully::Qualified::Plugin'

If you write a plugin, but put it in a non-standard namespace, you can use the fully qualified plugin namespace prefixed by '+'. Apart from the namespace treatment there is no difference in how the plugin is loaded or used.

'SomePlugin' => \@ARGS

Most plugins provide a fairly sane set of defaults when loaded. However some provide extras you need to request. When loading a plugin directly these would be the import arguments. If you plugin is followed by an arrayref the ref contents will be used as load arguments.

Bundles may also specify arguments for plugins. You can override the bundles arguments by specifying your own. In these cases last wins, arguments are never merged. If multiple bundles are loaded, and several specify arguments to the same plugin, the same rules apply.

    use Test::Stream(
        '-BundleFoo',         # Arguments to 'Foo' get squashed by the next bundle
        '-BundleAlsoWithFoo', # Arguments to 'Foo' get squashed by the next line
        'Foo' => [...],       # These args win
    );
'!UnwantedPlugin'

This will blacklist the plugin so that it will not be used. The blacklist will block the plugin regardless of where it is listed. The blacklist only effects the statement in which it appears; if you load Test::Stream twice, the blacklist will only apply to the load in which it appears. You cannot override the blacklist items.

'WantEverything' => '*'

This will load the plugin with all options. The '*' gets turned into ['-all'] for you.

'option' => ...

Uncapitalized options without a +, -, or : prefix are reserved for use by the loader. Currently there are no valid options, so any uncapitalized option will currently result in an exception. Test::Stream may in the future add any options it wants. As well loaders that subclass Test::Stream can add options of their own.

To define an option in your subclass simply add a _opt_name() method. The method will recieve 1 argument, a reference to the arguments array, it should shift off any arguments it expects.

    sub _opt_foo {
        my $self = shift;
        my ($args) = @_;

        my $arg = shift @$args; # Shift so that the loader does not treat it as
                                # a plugin or bundle.

        ...
    }

SEE ALSO

For more about plugins and bundles see the following docs:

plugins

Test::Stream::Plugin - Provides tools to help write plugins.

bundles

Test::Stream::Bundle - Provides tools to help write bundles.

EXPLANATION AND HISTORY

Test::Stream has learned from Test::Builder. For a time it was common for people to write Test::* tools that bundled other Test::* tools with them when loaded. For a short time this seemed like a good idea. This was quickly seen to be a problem when people wanted to use features of multiple testing tools that both made incompatible assumptions about other modules you might want to load.

Test::Stream does not recreate this wild west approach to testing tools and bundles. Test::Stream recognises the benefits of bundles, but provides a much more sane approach. Bundles and Tools are kept seperate, this way you can always use tools without being forced to adopt the authors ideal bundle.

ENVIRONMENT VARIABLES

This is a list of environment variables Test::Stream looks at:

TS_FORMATTER="Foo"
TS_FORMATTER="+Foo::Bar"

This can be used to set the output formatter. By default Test::Stream::Formatter::TAP is used.

Normally 'Test::Stream::Formatter::' is prefixed to the value in the environment variable:

    $ TS_FORMATTER='TAP' perl test.t     # Use the Test::Stream::Formatter::TAP formatter
    $ TS_FORMATTER='Foo' perl test.t     # Use the Test::Stream::Formatter::Foo formatter

If you want to specify a full module name you use the '+' prefix:

    $ TS_FORMATTER='+Foo::Bar' perl test.t     # Use the Foo::Bar formatter
TS_KEEP_TEMPDIR=1

Some IPC drivers make use of temporary directories, this variable will tell Test::Stream to keep the directory when the tests are complete.

TS_LB_PATH="./:./lib/:..."

This allows you to provide paths where Test::Stream will search for project specific bundles. These paths are NOT added to @INC.

TS_MAX_DELTA=25

This is used by the Test::Stream::Plugin::Compare plugin. This specifies the max number of differences to show when data structures do not match.

TS_TERM_SIZE=80

This is used to set the width of the terminal. This is used when building tables of diagnostics. The default is 80, unless Term::ReadKey is installed in which case the value is determined dynamically.

TS_WORKFLOW=42
TS_WORKFLOW="foo"

This is used by the Test::Stream::Plugin::Spec plugin to specify which test block should be run, only the specified block will be run.

TS_RAND_SEED=44523

This only works when used with the Test::Stream::Plugin::SRand plugin. This lets you specify the random seed to use.

HARNESS_ACTIVE

This is typically set by TAP::Harness and other harnesses. You should not need to set this yourself.

HARNESS_IS_VERBOSE

This is typically set by TAP::Harness and other harnesses. You should not need to set this yourself.

SOURCE

The source code repository for Test::Stream can be found at http://github.com/Test-More/Test-Stream/.

MAINTAINERS

Chad Granum <exodist@cpan.org>

AUTHORS

Chad Granum <exodist@cpan.org>

COPYRIGHT

Copyright 2015 Chad Granum <exodist7@gmail.com>.

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

See http://www.perl.com/perl/misc/Artistic.html