views:

57

answers:

2

So I've made a few modules for my own use, and I'm wondering if there is any documentation about how to write tests for perl modules using Module::Build.

The specific problem I'm running into is that I've got three modules, HomeBrew::IO, HomeBrew::Stats, and HomeBrew::Bio, and I can't figure out how to build or test them separately the way the files are arranged.

The three module files are located in the same directory .../HomeBrew/lib/HomeBrew/, and I've got three Build.PL files located in the .../HomeBrew/ directory (named IO-Build.PL, etc), and three .t files in .../HomeBrew/t/ (named HomeBrew-IO.t etc).

What seems to happen is that the three Build.PL files don't seem to know that they're only supposed to build one module at a time. I'll show you one of these:

#!/usr/bin/perl

use warnings;
use strict;
use Module::Build;

my $build = Module::Build->new
    (
     module_name => "HomeBrew::IO",
     dist_author => "George Locke",
     dist_abstract => "Various utilities for reading files",
     build_requires => {
        'Test::More' => '0.10',
        'POSIX' => '0', # for tmpname()
        'Test::Exception' => '0', # to test that checkExist dies
     },
    );
$build->create_build_script();

(I should probably be using File::Temp instead of POSIX, but this is only used in testing so it's not a high priority)

In the future, I would like to change my test scripts to have one for each subroutine so I can say Build test checkExist and check just one at sub at a time.

So,

  1. how do I make sure that create_build_script() doesn't include every single .pm file in the lib/HomeBrew. I'd prefer to keep all the HomeBrew module files within the .../HomeBrew directory, but do I have to separate out each one into different directories?

  2. How do I make tests for each subroutine such that Module::Build knows how to test a whole module or just one part of it?

right now, when I say ./Build test it tests all three modules at once (and ./Build install installs all three at once).

+5  A: 

It sounds to me like the issue is with your premise, that you need to build and test them separately. If you want to do that, they should be separate installations, in their own directories, with their own Build.PL files etc. If, however, they should be distributed together, they should be built and tested together.

As for testing things separately, you could test each sub in its own test file, or split up the tests in any other way you like. You don't have to invoke your tests with make test or ./Build test -- you can always just explicitly run the test(s) you care about: perl -Ilib t/<name of test>.

Ether
Thanks for your input. The main issue here is that I don't want to look at the test output for every subroutine in each module every time I change just one of them. I understand you to be saying that each module, and all the files associated with building and testing it, must be located in a separate directory (they are not inter-dependent, though they'd probably end up being distributed together if they get distributed at all). I'd also be interested if you could help with the 2nd part of my question (separately testing each sub).
flies
@flies: response edited!
Ether
@Ether thanks. last bit is especially helpful. I take it that `Build test` will just run every `.t` file in `t/` ?
flies
@flies: normally yes, but there are Module::Install directives to add other test directories as well (e.g. Module::Install::ExtraTests adds the `extra_tests` directive, which will run tests in the xt/ directory if various checks are true).
Ether
@Ether thanks again.
flies
It's better to build the distribution and run the modules from blib. It doesn't always matter, but it's a good habit to have when it does matter. In that case, it's `./Build; perl -Mblib t/test_name.t`
brian d foy
@brian: true enough; for modules with an XS component, it's the only place where the runnable code will exist! (BTW, you probably meant to say `-Iblib`, not `-Mblib`.)
Ether
Nope, I meant `-Mblib`. It loads the `blib` module. `-Iblib` won't work because Perl won't find any modules.
brian d foy
@brian: thanks, I mixed up the [module `blib`](http://perldoc.perl.org/blib.html) and the directory `blib/`. Taking a build system for granted is a double-edged sword. :)
Ether
+1  A: 

You say in your comment to Ether that you don't always want to run every test. In that case, you probably want to use App::Prove to run just the tests that you want to see. It has many other features to manage the information you track and see.

brian d foy
will look into it. app::prove isn't showing up on CPAN but it is at perldoc.org: http://perldoc.perl.org/App/Prove.html
flies
Huh, it's not in Test::Harness. It's kinda a dumb place for it other than a way to sneak it into core.
brian d foy