Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

How to export subs in a bin/script for testing in t/00.t

by leocharre (Priest)
on Feb 26, 2010 at 15:30 UTC ( #825537=perlquestion: print w/replies, xml ) Need Help??
leocharre has asked for the wisdom of the Perl Monks concerning the following question:

I have a small package that's just a command- it just contains a bin/script- a makefile, a readme, etc. The bin/script defines subroutines. I want to test these subroutines.

The usual kill here, is to move the subs into lib/

And t/00.t will use lib './lib' and test out subs in great.

What if I don't want to move subs from bin/script into lib/ for testing?

How can I use bin/script's subroutine definitions to use inside t/00.t, without running bin/script entirely??? I thought of maybe declaring a package inside bin/script, aside of main. But then, main will still run. Makes sense.

( Pseudo code follows.. This is an example bin/script )

#!/usr/bin/perl use strict; @ARGV or die("missing args"); map{ printf "%s\n", make_fun_of($_) } @ARGV; exit; sub make_fun_of { "I think @_ is funny." }
Great. I need to test make_fun_of() in my t/00.t ..
use Test::Simple 'no_plan'; require './bin/script'; # ????? for (qw/james cindy susan rob/){ ok( make_fun_of($_) ); }

Obviously, this is not going to work. So, how can I code bin/script in a way that allows it to.. I suppose optionally act a perl lib. Ideally, this would be done by declaring a separate package inside bin/script, one that's not in main. And t/00.t would somehow call that, and ignore main inside bin/script.. ??? (Sorry about the verbosity- I'm having difficulty asking the question.)

My main interest is that I want to keep the code in this one file, but I also want to test parts of it. Is this too greedy on my part and should I just forget it ( as in this is a waste of time ) ?

Replies are listed 'Best First'.
Re: How to export subs in a bin/script for testing in t/00.t
by ikegami (Pope) on Feb 26, 2010 at 15:54 UTC
    You can use caller to check if a script was loaded as a module.
      Oooh! Very cool!..

      I wrapped the part of the main body that runs stuff into a sub run() and then I have a line such as (in bin/script).. (pseudocode follows..)

      #!/usr/bin/perl caller() or run(); sub run { print do_stuff_1(); print do_stuff_2(); } sub do_stuff_1 { 1 } sub do_stuff_2 { 2 } 1;
      Then in t/00.t
      use Test::Simple 'no_plan'; require 'bin/script'; ok( do_stuff_1(), 'do_stuff_1()' );
      Thank you! This is a wonderful solution. (Maybe someone has another (more elegant, less intrusive?) way to do this?)
        Maybe not more elegant but the name "main" instead of "run" would be a more common convention. Actually google found this exact example here, putting a package name at the top, and calling
        __PACKAGE__->main() unless caller();

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://825537]
Approved by marto
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2018-06-23 07:15 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (125 votes). Check out past polls.