Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Anyone want Test::Class::Moose?

1 view
Skip to first unread message

chromatic

unread,
Dec 12, 2012, 12:58:01 PM12/12/12
to per...@perl.org, Ovid
On Wednesday, December 12, 2012 09:51:27 AM Ovid wrote:

> So, does this look useful for folks?

Yes, please. I would use it last month if I could.

> Is there anything you would change?

I don't *love* maintaining individual driver files (t/subsystem/feature.t),
but I do like being able to run test classes individually with:

$ prove -l t/subsystem/feature.t

Is that easy to support?

-- c

Ovid

unread,
Dec 12, 2012, 1:07:35 PM12/12/12
to chromatic, Perl QA
>________________________________
> From: chromatic <chro...@wgz.org>


>> Is there anything you would change?
>
>I don't *love* maintaining individual driver files (t/subsystem/feature.t),
>but I do like being able to run test classes individually with:
>
>    $ prove -l t/subsystem/feature.t
>
>Is that easy to support?


Shouldn't be too hard. Maybe have a DEMOLISH which checks to see if the tests have been run and run them with a default (empty) constructor if they haven't.

Cheers,
Ovid
--
Twitter - http://twitter.com/OvidPerl/
Buy my book - http://bit.ly/beginning_perl
Buy my other book - http://www.oreilly.com/catalog/perlhks/
Live and work overseas - http://www.overseas-exile.com/

Mark Stosberg

unread,
Dec 12, 2012, 1:15:10 PM12/12/12
to Ovid, Perl QA

> So, does this look useful for folks? Is there anything you would change? (It's trivial to assert plans for classes and the entire test suite rather than rely on done_testing(), but I haven't done that yet).

I would welcome it as an option.

We use Test::Class now, but I have the sense that there's a better
alternative. We have started to load Moose in most cases, so there's no
additional load time penalty for Moose since it's already there.

Some things I like from some alternatives (from reviewing them, not
using them):

I like the declarative style and simple nesting of Test::Spec:

https://metacpan.org/module/Test::Spec

describe "A User object" => sub {
my $user;
before sub {
$user = User->new;
};
describe "from a web form" => sub {
before sub {
$user->init_from_tree({ username => "bbill", ... });
};
it "should read its attributes from the form";
describe "when saving" => sub {
it "should require a unique username";
it "should require a password";
};
};
};

Test::Ika has a similar spirit, but with an option for very readable output:

describe 'MessageFilter' => sub {
my $filter;

before_each {
$filter = MessageFilter->new();
};

it 'should detect message with NG word' => sub {
my $filter = MessageFilter->new('foo');
expect($filter->detect('hello foo'))->ok;
};
it 'should detect message with NG word' => sub {
my $filter = MessageFilter->new('foo');
expect($filter->detect('hello foo'))->ok;
};
};

Check out the TAP-alternative output here:

https://metacpan.org/module/Test::Ika

This is a good idea that I expect to spread: Generating TAP for test
harnesses, but more a readable format when the target is a human reader.

However, I think if I just wanted to mash-up Test::Class and Moose, I
would do something more like this:

package Test::Class::Moose;
use Moose;
use MooseX::NonMoose;
extends 'Test::Class';

####

That way I would have to update our hundreds of test scripts to use a
new syntax. :) If your project is to be considered a path forward from
Test::Class but with an incompatible syntax, it would be great if it
came with a script to find/replace the old syntax with the replacement.


Mark

Jonathan Swartz

unread,
Dec 12, 2012, 1:18:49 PM12/12/12
to Ovid, Perl QA
+1 from me! I like Test::Class and would welcome a Moose-ish variety.

On Dec 12, 2012, at 9:51 AM, Ovid <publiuste...@yahoo.com> wrote:

> Hi all,
>
> People keep asking me how to properly integrate Moose with Test::Class. I know about Test::Able and some alternatives, but I *generally* like Test::Class's interface (or maybe I'm just in a comfort zone). So I wrote my own Test::Class::Moose (it does not use Test::Class) and it uses subtests all the way down.
>
> Every test class is one test. Every test method is a subtest in the test class. Every test in a test method is, well, one test in a test method. Here's a simple test class which, in turn, inherits from another test class (you get all of the functions from Test::Most along with Moose helper functions, if desired):
>
> package TestsFor::Basic::Subclass;
> use Test::Class::Moose parent => 'TestsFor::Basic';
>
> sub test_startup {
> my $test = shift;
> $test->next::method;
> # more startup here, but tests are not allowed
> }
>
> sub test_me {
> my $test = shift;
> my $class = $test->this_class;
> ok 1, "I overrode my parent! ($class)";
> }
>
> before 'test_this_baby' => sub {
> my $test = shift;
> my $class = $test->this_class;
> pass "This should run before my parent method ($class)";
> };
>
> sub this_should_not_run {
> fail "We should never see this test";
> }
>
> sub test_this_should_be_run {
> for ( 1 .. 5 ) {
> pass "This is test number $_ in this method";
> }
> }
>
> 1;
>
> Note that attributes are not required on the test methods. Methods which start with "test_" are considered test methods (you can override this behavior, of course). That includes the test control methods of test_startup(), test_setup(), and so on.
>
> You should be able to consume roles or use the rest of Moose any way you think you should.
>
> Here's how we load and run tests:
>
> use Test::Class::Moose::Load qw(t/lib);
>
> Test::Class::Moose->new({
> # timing on a class and method level
> show_timing => 0,
> # how many classes, methods and tests
> statistics => 1,
> })->runtests;
>
> My main concern is that the nested subtests will annoy people:
>
> #
> # Executing tests for TestsFor::Basic::Subclass
> #
> # TestsFor::Basic::Subclass->test_me()
> ok 1 - I overrode my parent! (TestsFor::Basic::Subclass)
> 1..1
> ok 1 - test_me
> # TestsFor::Basic::Subclass->test_this_baby()
> ok 1 - This should run before my parent method (TestsFor::Basic::Subclass)
> ok 2 - whee! (TestsFor::Basic::Subclass)
> 1..2
> ok 2 - test_this_baby
> # TestsFor::Basic::Subclass->test_this_should_be_run()
> ok 1 - This is test number 1 in this method
> ok 2 - This is test number 2 in this method
> ok 3 - This is test number 3 in this method
> ok 4 - This is test number 4 in this method
> ok 5 - This is test number 5 in this method
> 1..5
> ok 3 - test_this_should_be_run
> 1..3
> ok 1 - TestsFor::Basic::Subclass
> #
> # Executing tests for TestsFor::Basic
> #
> # TestsFor::Basic->test_me()
> ok 1 - test_me() ran (TestsFor::Basic)
> ok 2 - this is another test (TestsFor::Basic)
> 1..2
> ok 1 - test_me
> # TestsFor::Basic->test_this_baby()
> ok 1 - whee! (TestsFor::Basic)
> 1..1
> ok 2 - test_this_baby
> 1..2
> ok 2 - TestsFor::Basic
> 1..2
> # Test classes: 2
> # Test methods: 5
> # Total tests run: 11
> ok
> All tests successful.
> Files=1, Tests=2, 2 wallclock secs
> Result: PASS
>
> So, does this look useful for folks? Is there anything you would change? (It's trivial to assert plans for classes and the entire test suite rather than rely on done_testing(), but I haven't done that yet).
>

Ovid

unread,
Dec 13, 2012, 2:05:47 AM12/13/12
to Jonathan Swartz, Perl QA
It's seriously alpha and has a nasty bug whereby an exception will halt the entire test suite.

I can fix that later, but I wanted to get something out for you folks.

https://github.com/Ovid/test-class-moose

 
Note that I elected to not use attributes because they're hard for *you* to customize, but it's trivial for you to override the get_test_classes() and get_test_methods() behavior for your own testing purposes.

More work needs to be done, but I think you'll be pleased at how short the code is to do this.


>________________________________
> From: Jonathan Swartz <swa...@pobox.com>
>To: Ovid <publiuste...@yahoo.com>
>Cc: Perl QA <per...@perl.org>
>Sent: Wednesday, 12 December 2012, 19:18
>Subject: Re: Anyone want Test::Class::Moose?

Justin DeVuyst

unread,
Dec 14, 2012, 1:54:25 PM12/14/12
to per...@perl.org
All,

What's wrong with Test::Able?

-jdv

Ovid

unread,
Dec 15, 2012, 5:37:04 PM12/15/12
to Justin DeVuyst, per...@perl.org
Hi Justin,

This is something I've wondered as well. Several times when people asked me about using Test::Class with Moose I pointed them to Test::Able, though I confess I never used that code. Invariably they would not choose it. I think what's going on is the interface. It looks "different" and that's possibly scaring people off. The interface for Test::Class::Moose looks very similar to Test::Class and that might make for easier adoption if I ever do enough to get it out of alpha.

Please note that I'm not saying that what I've written is better! However, the comfort level of the Test::Class::Moose interface may be appealing to some.


 
Cheers,
Ovid
--
Twitter - http://twitter.com/OvidPerl/
Buy my book - http://bit.ly/beginning_perl
Buy my other book - http://www.oreilly.com/catalog/perlhks/
Live and work overseas - http://www.overseas-exile.com/


>________________________________
> From: Justin DeVuyst <jus...@devuyst.com>
>To: per...@perl.org
>Sent: Friday, 14 December 2012, 19:54


>Subject: Re: Anyone want Test::Class::Moose?
>

Mark Stosberg

unread,
Dec 17, 2012, 9:14:57 AM12/17/12
to per...@perl.org
On 12/15/2012 05:37 PM, Ovid wrote:
> Hi Justin,
>
> This is something I've wondered as well. Several times when people asked me about using Test::Class with Moose I pointed them to Test::Able, though I confess I never used that code. Invariably they would not choose it. I think what's going on is the interface. It looks "different" and that's possibly scaring people off. The interface for Test::Class::Moose looks very similar to Test::Class and that might make for easier adoption if I ever do enough to get it out of alpha.
>
> Please note that I'm not saying that what I've written is better! However, the comfort level of the Test::Class::Moose interface may be appealing to some.

There's also Test::Sweet-- another Moose/Test::Class mashup which I
haven't developed an opinion of: https://metacpan.org/module/Test::Sweet

I can see that one difference is that it uses Devel::Declare.

As I looked more at Test::Class::Moose, one thing I really like is that
plans are completely gone. Thank you.

Two questions:

1. About this: "use Test::Class::Moose;"

Why not standard inheritance to add Test::Class functionality?

It looke the rationale here is to save a line of boilerplate with the
"use Moose" line.

2. About this syntax for extending a test class:
use Test::Class::Moose parent => 'TestsFor::Some::Class';

why not use standard inheritance in a class, and to extend a class using
test::Class? Or could you 'extends' in the import list here to look more
Moose-y?

Mark







Ovid

unread,
Dec 17, 2012, 9:49:15 AM12/17/12
to Mark Stosberg, per...@perl.org
Hi Mark,

>________________________________
> From: Mark Stosberg <ma...@summersault.com>


>As I looked more at Test::Class::Moose, one thing I really like is that
>plans are completely gone. Thank you.

You're welcome. They're inferred at the suite and class level, but with an implicit "done_testing()" for each method. It's not perfect, but there alternatives seemed a touch worse.

>Two questions:
>
>1. About this: "use Test::Class::Moose;"
>
>Why not standard inheritance to add Test::Class functionality?
>
>It looke the rationale here is to save a line of boilerplate with the
>"use Moose" line.

Test::Class::Moose is explicitly coupled with Moose, so having a "use Moose" line is both redundant and error-prone. If it's required and you forget it, oops. I've given you a source of bugs you didn't need. If it's not required, why write it?

>2.  About this syntax for extending  a test class:
>  use Test::Class::Moose parent => 'TestsFor::Some::Class';
>
>why not use standard inheritance in a class, and to extend a class using
>test::Class? Or could you 'extends' in the import list here to look more
>Moose-y?


I think "extends" might be better. Good call.

I don't use standard inheritance because the various solutions for that don't allow for both inheriting from a class and exporting functions (in this case, ok(), is(), eq_or_diff(), and so on).

0 new messages