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

NAME

POE::Test::Helpers - Testing framework for POE

VERSION

Version 0.05

SYNOPSIS

This module provides a Moose role to allow you to test your POE code.

Currently it's best used with MooseX::POE but POE::Session code is also doable.

Perhaps a little code snippet.

    package MySession;
    use MooseX::POE;
    with 'POE::Test::Helpers';

    has '+seq_ordering' => ( default => sub { {
        last => { 1 => ['next'] },
    } } );

    event 'START' => sub {
        $_[KERNEL]->yield('next');
    };

    event 'next' => sub {
        $_[KERNEL]->yield('last');
    };

    event 'last' => sub {
        ...
    };

    package main;
    use Test::More tests => 2;
    use POE::Kernel;
    MySession->new();
    POE::Kernel->run();

    ...

Testing event-based programs is not trivial at all. There's a lot of hidden race conditions and unknown behavior afoot. Usually we separate the testing to components, subroutines and events. However, as good as it is (and it's good!), it doesn't give us the exact behavior we'll get from the application once running.

There are also a lot of types of tests that we would want to run, such as:

  • Ordered Events:

    Did every event run in the specific ordered I wanted it to?

    (maybe some event was called first instead of third...)

  • Sequence Ordered Events:

    Declaring dependency events for tested events.

    (an event is only okay if the preceeding events ran first)

  • Event Counting:

    How many times can each event run?

    (this event can be run only 4 times, no more, no less)

  • Ordered Event Parameters:

    Checking specific parameters an event received, supporting multiple options.

    (did this event get the right parameters for each call?)

  • Unordered Event Parameters:

    Same thing, just without having a specific order of sets of events.

This module allows to do all those things using a simple Moose Role.

In order to use it, you must consume the role (using with) and then change the following attributes.

Attributes

seq_ordering

This is a hash reference which sets the number of times each event can be run and/or the event that had to come first before the event could be run. That is, if you have an event "world", you can specify that "world" can only be run once, or can only be run twice. You can instead specify that "world" can only be run after a different event - "hello" - has been run.

Here are some examples:

    has '+seq_ordering' => ( default => sub { {
        hello => 1,                  # hello can only be run once
        there => ['hello'],          # there can only be run after hello
        world => { 2 => ['hello'] }, # world has to be run twice and only after hello
    } } );

One thing to remember is that event dependencies are not direct. That is, in the above example, "world" can be run right after "there" but as long as "hello" was run sometime prior to that, it will be okay. That is, sequence ordering is not strict.

event_params

This is a hash reference which sets the parameters each event is expecting. By default, this parameters must be consecutive. That is, if there are two sets of parameters, the first one is what's tested when the event is run for the first time and the second one will be tested when the event is run the second time. If this is troublesome for you, check the next attribute, you'll enjoy that.

    has '+event_params' => ( default => sub { {
        goodbye => [ [ 'cruel',  'world' ] ],
        hello   => [ [ 'ironic', 'twist' ] ],
        special => [ [ 'params', 'for', first', 'run' ], [ 'params', 'for', 'second' ] ],
    } } );

You'll notice one weird thing: two array refs. The reason is actually very simple. This test checks each parameter separately, so you specify sets of parameters, each set for a different run. Thus, each set is defined in an array ref. Because of this, even if you're only giving one set of params, it needs to be encapsulated in an array ref. This might change in the future, if anyone will care enough.

event_params_type

This is a simple string which controls how the event_params will go. Meanwhile it can only be set to "ordered" and "unordered". This might change in the future or could be replaced with "event_params_ordered" boolean or something. Be warned.

Basically this means that you don't care about the order of how the parameters get there, but only that whenever the event was run, it had one of the sets of parameters.

METHODS

order

Simple ordered tests can also be done using this framework, but are less intuitive. In order to set orders of events, a method has to be run. I'm sure this will be changed, so stay tuned.

    event 'example' => sub {
        my $self = $_[OBJECT];
        $self->order( 0, 'Example runs first!' );
    };

AUTHOR

Sawyer, <xsawyerx at cpan.org>

BUGS

Please report any bugs or feature requests to bug-poe-test-simple at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=POE-Test-Simple. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc POE::Test::Simple

You can also look for information at:

ACKNOWLEDGEMENTS

I owe a lot of thanks to the following people:

  • Chris (perigrin) Prather

    Thanks for all the comments and ideas. Thanks for MooseX::POE!

  • Rocco (dngor) Caputo

    Thanks for the input and ideas. Thanks for POE!

  • #moose and #poe

    Really great people and constantly helping me with stuff, including one of the core principles in this module.

COPYRIGHT & LICENSE

Copyright 2009 Sawyer, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.