Extensive POE Testing PT. 6 - Testing, Event Parameters PT.1

xsawyerx on 2009-10-28T08:27:52

There is actually a limit on the length of the subject, this should actually be entitled: Extensive POE Testing PT. 6 - Testing, Ordered Event Parameters

We've covered the rules, ordered tests, sequence ordered tests, event counting and a mixture of event counting and sequence ordered tests. Now it's time to play with some more advanced stuff.

The last frontier I came across trying to battle testing in POE was wanting to make sure the parameters to each event were what I expected. Why?

  • I'm able to test who called what and how many times, but if the parameters change, how would I know?
  • What if there an error in a function that's hard to test and it calls incorrect parameters?
  • What if I have a race condition?

So, naturally, I wanted to know what parameters are sent to each event. This is how it can be done with my POE::Test::Helpers 0.06:

package Session;
use Test::More tests => 4; # this can also be defined in main
use MooseX::POE;
with 'POE::Test::Helpers';

has '+event_params' => ( default => sub { {
    next => [ [ 'hello', 'world' ], [ 'goodbye' ] ],
    more => [],
} } );

# a flag for making sure next runs again
my $flag = 0;

# set up the events
sub START { $_[KERNEL]->yield( 'next', qw( hello world ) ) }

event 'next' => sub { $_[KERNEL]->yield('more') };
event 'more' => sub {
    $flag++ || $_[KERNEL]->yield( 'next', 'goodbye' );
};

# set up main
package main;
use POE::Kernel;
Session->new();
POE::Kernel->run();

What happens when the Kernel is run is that:

  • START -> next (parameters: "hello", "world")
  • next -> more (no parameters)
  • more -> next (parameters: "goodbye")
  • next -> more (no parameters)
  • more does nothing and the program closes.

What we can see is that we defined with our helpers the assumed iterations of each event. next is assumed to first run with the parameters "hello" and "world", and secondly run with the parameter "goodbye". We also assume that more will be called with no parameters at all.

These are the results of the test:

1..4
ok 1 - (next) Correct params
ok 2 - (more) Correct params
ok 3 - (next) Correct params
ok 4 - (more) Correct params

This helps make sure the events run with the exact parameters we want for each run, in the order we specified. This is extremely important to understand. It checks that you called it first with the first parameter set (in an arrayref) and only then with the second one. If by some weird turn of events (or code editing), the calls would get mixed up and it will call next with "goodbye" first, the test will fail.

This is how it would look if we reverse the order of the parameters:

not ok 1 - (next) Correct params
#   Failed test '(next) Correct params'
#   at lib/POE/Test/Helpers.pm line 94.
# Comparing $data as a Bag
# Missing: 'goodbye'
# Extra: 'hello', 'world'
ok 2 - (more) Correct params
not ok 3 - (next) Correct params
#   Failed test '(next) Correct params'
#   at lib/POE/Test/Helpers.pm line 94.
# Comparing $data as a Bag
# Missing: 'hello', 'world'
# Extra: 'goodbye'
ok 4 - (more) Correct params
# Looks like you failed 2 tests of 4.

One question remains: what if I can't know the order? What if I don't care? What if either of them can run but I don't know which one would come before the other? That's left for the next post.

BTW, as promised, I will demonstrate how to test for a pretty nasty race condition using these methods, easily.