Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

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
[Cosmic37]: I'm wondering whether there is a specific/(or at least "usual") command or does one take a copy before undefining and then copy it back after slurping file into a string?
[BarApp]: I need help accessing perl files. I need permission!!!
[Cosmic37]: I wish thee a peachy life and express gratitude for considering my pathetic questions
[erix]: record separator
[Cosmic37]: Permissions are interesting earthlings. Did nature determine who gives permission and who asks permission. Who was the first to get permission? Are you not related to them as one big earthling family?

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (9)
As of 2017-06-29 16:35 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (672 votes). Check out past polls.