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

This is a pretty amateur question but .. I've written a large testing suite program which runs through a sequence of tests by calling them. Each of these called subtest programs have statements that print at then end to display the results of that subtest. My problem is that I'm only getting the print out from the main program but not from the individual programs that get invoked (and finish successfully) It appears to not print unless I capture it or redirect it to another file, but for ease of use I'd rather not have to go and open a rather large sequence of files just to see their output (not to mention that I really dont want to have to store too many unnecessary files). I just want to see all the program print outs displayed in the terminal. Thank you!

Replies are listed 'Best First'.
Re: How to print called program to stdout
by 1nickt (Canon) on Mar 18, 2016 at 18:09 UTC

    Hi! There's more than one way to do it, but some wheels not only have already been invented, but are really, um ... round.

    Everything you say that you want to do is provided by Perl's built-in testing tools. See in particular Test::More::subtest().

    Hope this helps!


    The way forward always starts with a minimal test.
Re: How to print called program to stdout
by Anonymous Monk on Mar 18, 2016 at 17:27 UTC
    To clarify I (from what I've learned at this point) that perhaps the best way is to just capture the output of the subprogram when it is called from the main program then just print it out from main when it returns. However, I'd like to see the printout of the test results as the subprogram runs, so that I know something failed at that moment instead of having to wait until the entire test subprogram completes to gather my results?

      This may not be what you're looking for, but when I'm testing a script, I redirect STDERR to print to STDOUT. That way I can pepper my script with print statements to see what is going on so that I can debug it. This is how I do it:

      BEGIN { $| = 1; open(STDERR, ">&STDOUT"); print "Content-type: text/html\n\n"; }

      Hope that assists you.

      $| =1; is a key thing.

      What $| =1; does is un-buffer STDOUT. STDERR is already un-buffered by default.

      What buffering does is to gather up stuff until it reaches a "quanta" of stuff to write. Then the O/S writes it all at once. This difference matters a lot in terms of performance. For writing to a HD, maybe 4Kbytes or 8Kbytes might be the "quanta" for stdout.

      When $|=1 is in effect, each print statement will actually access the HD for every print.

      Note that you can redirect stdout and stderr individually from the command line. The default is only re-direct stdout, "someprog >stdoutfile"."command > combinedfile 2>&1" re-directs both std-err and std-out to the same file.

      For some programs that run for a long time on the command line, I use stderr to print status, "working on X..". I do that so that I can see that the program is not "hung". And I send any actual error to both stderr and stdout.

      I think that all you need to do is set: $|=1; When you do that, the "errors" and the "output" will occur together on the stdout console. When you have the program working, then take $|=1; out if you want it to run faster. $|=1 eliminates the delay between an error and the next stdout line, also stdout lines appear in "real time" instead of there being a delay. It is certainly possible that if the "buffering write quanta" is not fulfilled, that the program doesn't print anything until it actually has already exited!

        I only use that on web servers. I want it to print back to the output so I can see the results in the browser. I never use it on my local machine.

      There are some details that would help make it easier to answer your questions. 1) What is the form of the output from your subprograms? (ie, Do they print to STDOUT or STDERR, or do they just return a value?). 2) How are you calling the subprograms from your main program? (ie, as direct function/method calls, or by system() calls or qx// or ``).

      Because if your subprograms are just printing to STDOUT, and you are calling them from your main program via function/method calls, it surprises me that you cannot see their output. But if you are calling a separate process (which your use of "program" rather than "function" or "method" might indicate) using a system() call, then you are going to have to switch to a print `subprogram` paradigm, otherwise the separate process's output will be lost to the system()'s ether.

      Update: Specifically, if your mainprogram.pl looks like:

      #!perl use warnings; use strict; use MyModuleToBeTested; callSomeFunctionThatPrintsToSTDOUT();
      ... then i don't see why it wouldn't print.

      OTOH,

      #!perl use warnings; use strict;
      system("callSomeProgram");
      print `runASecondProgram`;
      ... will not print anything from "callSomeProgram", because system() doesn't output, whereas it will print the STDOUT from "runASecondProgram" because of your print statement.

      edit: strikeout patently false info and fix typos from the fix. Thanks choroba

        > because system() doesn't output

        It does. system prints to STDOUT, you just can't access its output from the calling Perl program:

        $ perl -we 'system "date"' Sat Mar 19 10:48:46 CET 2016
        ($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,