nysus has asked for the wisdom of the Perl Monks concerning the following question:

So, I know enough about the basics of test driven development to want to start worrying about how to make things more painless. I've got code like this in my tests to make sure my Moose classes has the attributes/methods/packages it needs to run correctly:

ok $INC{'DB.pm'}, 'DB module loaded'; ok $INC{'Moose.pm'}, 'Moose module loaded'; ok $INC{'StevesPerlTools.pm'}, 'StevesPerlTools module loaded'; ok $INC{'Modern/Perl.pm'}, 'Modern::Perl module loaded'; ok $INC{'LaborData/Data/Dir.pm'}, 'LaborData::Data::Dir module loaded' +; ok $INC{'StevesPerlTools.pm'}, 'StevesPerlTools module loaded'; #ok $INC{'Web/Scraper.pm'}, 'Web::Scraper module loaded'; my $i; lives_ok { $i = LaborData::Data::Importer->new } 'does not throw error + with no argument passed'; # check that needed attributes are created and are proper type is 1, $i->meta->has_attribute('raw_data'), 'has an \'raw_data\' attrib +ute'; is 'LaborData::Data::Dir', $i->meta->get_attribute('raw_data')->type_c +onstraint, 'raw_data attribute is a \'LaborData::Data::Dir\''; is (attribute_is_ro($i, 'raw_data'), 1, 'raw_data is read only'); is (!! $i->can('create_db'), 1, 'can create database'); is (!! $i->can('destroy_db'),1, 'can destroy database'); is 1, !! $i->can('_get_columns'), 'can get columns'; # etc;

Obviously, a lot of this is repetitive and it's a lot of typing for stuff that will probably pass once and will likely never break again. Still, I'd feel better if I did test my class as a sanity check. I'm assuming there is some kind of framework for automating this. I've looked briefly at Test::Class::Moose but I'm not quite sure if it can help automate the kind of tests I'm running in my code above (like attribute properties, for example).

And guidance is appreciated.

UPDATE
As I think about this more, I guess what I'd be looking for is to be able to write a class definition into some file and run a script that would automatically generate the Moose class and the tests for me. Does such a beast exist?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Automation of testing of Moose class structure
by choroba (Cardinal) on Feb 10, 2017 at 22:24 UTC
    The fact that
    has raw_data => (is => 'ro');

    creates a read only attribute called raw_data is already tested in the test suite of Moose itself. Test only the public methods of your classes.

    (Well, you should also test complex type constraints etc., but you get the idea.)

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      But let's say I accidentally change the wrong attribute property. Moose has no knowledge of what my intentions are.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

Re: Automation of testing of Moose class structure
by Anonymous Monk on Feb 10, 2017 at 20:49 UTC

    "... able to write a class definition into some file and run a script that would automatically generate the Moose class and the tests for me ..."

    How would you tell the definition what methods to call and how would you pass the necessary arguments to them? How would this process know what values to expect?

    Just write the tests and be done with it. Don't worry about DRY with unit tests. The more repetitive and explicit the better. Leave clever out of your unit tests -- try to avoid loops as much as possible. Each test should be able to comment out with a simple # -- loops make you code in exceptions. Unit tests should be KISS - keep it simple and stupid. Study the unit tests in your favorite CPAN distributions: some are great and some are not so good and some are downright embarrassing.

    Make your unit tests double as working examples of your code. Simple tests. Simple one line examples.

      It would just set up the skeleton based on variables passed to it. and print out out something like:

      use Moose; use this; ust that; has this => (is => 'ro', isa => 'that'); sub do_this { my $self = shift; confess 'not implemented'; }
      The config file would look something like this:
      $use = ['Moose, 'this', 'that';] $attributes = {name => 'this', {is => 'ro', isa => 'that'}; $methods = ['do this'];

      Maybe a templating system is better with some kind of vim plugin in. I just don't know. I'm sure this kind of thing has been done before. I'm not trying to reinvent the wheel just trying to figure out which wheel to use for this task. All I know is I'm bored stiff typing out the same thing over and over and fixing dumb typos which eat up a crap load of time. I'd rather just focus on constructing the building instead of setting up scaffolding.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

      Had to look up DRY. Thanks. Good advice, but I'm not sure it applies to something as mundane as checking that I don't accidentally break the code when editing. Do I really want the pain of writing 3 or 4 lines of code for every single attribute to make sure its parameters for it weren't accidentally changed by me?

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

Re: Automation of testing of Moose class structure
by nysus (Parson) on Feb 10, 2017 at 16:53 UTC
Re: Automation of testing of Moose class structure
by nysus (Parson) on Feb 10, 2017 at 18:50 UTC