After a lot of frustration of trying to set up proper tests for POE (using mainly MooseX::POE while at it), I've decided to write a proper testing framework. However, instead I wrote something simple, yet relatively extensive that helps write fingergrained tests for POE using Moose, specifically aimed towards MooseX::POE.
I've decided to write it in Moose (using Moose::Role) because it makes it much easier for me to do it than other frameworks/modules. I don't intend (at least at this time) to write it in bare bones Perl and I personally don't care about complete optimizations for my testing code, I don't think a lot of people would mind either.
This article will only discuss the general need, the idea and the general rules I've layed out for myself to help me test POE code. It might help you too. The following articles in this series (and I assure you, there will be!) discuss the types of tests that I feel are required and examples of code that does it. I'll also present my new (unnamed) testing framework that's already being used at $work.
Preliminary:
In POE, you have a layer of "events" which are actually just mappings of names of events that can be run to the actual subroutines that they will trigger when run. This seems pretty simple to test. You can check each subroutine separately and that's just fine. However, there are some things it doesn't cover:
inline_states
(or whatever), you simply do event 'something' => sub {};
Problem is, you cannot test it that easily.
Theory of tests in POE:
I found that the cleanest and easiest way to test is always accompanied by these following guidelines:
Next post starts with types of tests!
package Foo;
use 5.10.0;
use MooseX::POE;
event bar => sub { say 'BAR!' };
package main;
Foo->new->bar(); # prints "BAR!\n"
Also any tests that you happen to want to push back into MooseX::POE will be *greatly* appreciated. The code is available on github.
Re:A slight clarification ...
xsawyerx on 2009-10-08T09:23:48
Thanks for the clarification. I reckon that going through MX::POE code, I could also probably make my framework even better. Right now each event requires adding a line in order for the framework to track it. If I could get a list of the events, I could put in the added line myself perhaps.
I'm also checking into Sub::Caller or stack modules to try and remove the need for parameters to the added line.
Once I decide how to name my framework, I'll put it on Github and CPAN and people will (hopefully) be able to [help me] improve it much more.
Re:A slight clarification ...
perigrin on 2009-10-08T16:38:11
The event are stored in the metaclass.
my @events = $self->meta->get_events;
I've been going through the code myself recent, cleaning up an edge case bug that someone discovered, and modernizing the codebase a bit (the next version will depend on Moose 0.90+ but drops the MooseX::AttributeHelpers dependency).
Re:A slight clarification ...
xsawyerx on 2009-10-08T17:03:45
That's awesome!
Do you know if there's any way to get the arguments a method you've hooking to is getting? For example:
package A;
use Moose;
sub hello {
my ( $self, $msg ) = @_;
say $msg;
}
package B;
use Moose;
extends 'A';
before 'hello' => sub {
# i want to get the $msg parameter hello() got
};Re:A slight clarification ...
perigrin on 2009-10-09T05:57:47
Is this what you are asking for?
#!/usr/bin/env perl
use strict;
use Test::More tests => 6;
{
package Base;
use MooseX::POE;
sub START {
::pass('Base Start');
}
event hello => sub {
::pass('hello');
$_[KERNEL]->yield('goodbye');
};
}
{
package Extended;
use MooseX::POE;
extends 'Base';
sub START {
::pass('Extended after Start');
$_[KERNEL]->yield( 'hello' => 'world' );
}
before 'hello' => sub {
::is( $_[ARG0], 'world', 'before saw world' );
};
after 'hello' => sub {
::is( $_[ARG0], 'world', 'after saw world' );
};
event goodbye => sub {
::pass('goodbye');
};
}
my $foo = Extended->new();
POE::Kernel->run();I've just added this to the test suite.
Re:A slight clarification ...
xsawyerx on 2009-10-09T15:32:31
Actually it is!
This would really help me with the framework. I could automatically hook up to all events. Putting it in will make my code able to work automatically by adding only a single line of "with".
Thanks!
Re:A slight clarification ...
perigrin on 2009-10-11T18:01:02
Sorry, I wasn't clear. That code works *now*. It should work in the CPAN version. Go forth and test away!