0

Is there a Perl module which can test the CGI output of another program? E.g. I have a program

x.cgi

(this program is not in Perl) and I want to run it from program

test_x_cgi.pl

So, e.g. test_x_cgi.pl is something like

#!perl
use IPC::Run3
run3 (("x.cgi"), ...)

So in test_x_cgi.pl I want to automatically check that the output of x.cgi doesn't do stupid things like, e.g. print messages before the HTTP header is fully outputted. In other words, I want to have a kind of "browser" in Perl which processes the output. Before I try to create such a thing myself, is there any module on CPAN which does this?

Please note that x.cgi here is not a Perl script; I am trying to write a test framework for it in Perl. So, specifically, I want to test a string of output for ill-formedness.

Edit: Thanks

I have already written a module which does what I want, so feel free to answer this question for the benefit of other people, but any further answers are academic as far as I'm concerned.

5 Answers 5

2

There's CGI::Test, which looks like what you're looking for. It specifically mentions the ability to test non-Perl CGI programs. It hasn't been updated for a while, but neither has the CGI spec.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks cjm, you are always so helpful. I'll take a look at that and if it does what I want I'll mark this as the accepted answer.
This one seems to fail its own tests, so I'm not hopeful. CPAN testers says: PASS (2) FAIL (238) NA (1) UNKNOWN (41).
I thought maybe I could salvage something from this, but unfortunately it looks like this was never a real module, just a bunch of documentation and stub functions which don't actually do anything much, and then both of the authors abandoned it eight years ago without completing it. But thanks for the suggestion anyway. What I'll do now is to write my own module.
Whoever upvoted this (apart from me) should explain themselves, this module is a dog.
1

There is Test::HTTP. I have not used it, but seems to have an interface that fits your requirements.

$test->header_is($header_name, $value [, $description]);

Compares the response header $header_name with the value $value using Test::Builder-is>.

$test->header_like($header_name, $regex, [, $description]);

Compares the response header $header_name with the regex $regex using Test::Builder-like>.

2 Comments

Thanks but again unfortunately this is not what I want, because this works by sending an HTTP request to a server. The problem I have is I want to check that x.cgi doesn't do shitty things like printing something out before the headers have been sent etc. If x.cgi has those kinds of problems, then it will not work under a server environment, the server will just send a status 500 back to the testing framework, which is no use because I have no idea what part of x.cgi was responsible for the misbehaviour.
Sorry, hold on; it has a method to create a fake user agent, which looks promising. OK I will investigate further.
0

Look at the examples from chapter 16 from the perl cookbook

16.9. Controlling the Input, Output, and Error of Another Program

It uses IPC::Open3. Fom perl cookbook, might be modified by me, see below.

Example 16.2

cmd3sel - control all three of kids in, out, and error.

use IPC::Open3;
use IO::Select;


$cmd = "grep vt33 /none/such - /etc/termcap";
 my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $cmd);

$SIG{CHLD} = sub {
    print "REAPER: status $? on $pid\n" if waitpid($pid, 0) > 0
};

#print CMD_IN "test test 1 2 3 \n";
close(CMD_IN);

my $selector = IO::Select->new();
$selector->add(*CMD_ERR, *CMD_OUT);

while (my @ready = $selector->can_read) {
    foreach my $fh (@ready) {
        if (fileno($fh) == fileno(CMD_ERR)) {print "STDERR: ", scalar <CMD_ERR>}
        else                                {print "STDOUT: ", scalar <CMD_OUT>}
        $selector->remove($fh) if eof($fh);
    }
}
close(CMD_OUT);
close(CMD_ERR);

3 Comments

-1 downvote from me. I guess you didn't read the question or the answers already given.
you wrote: "I want to have a kind of "browser" in Perl which processes the output. " CGI scripts produce output by printing an HTTP message on STDOUT.
I'm sorry you feel that way, but I have made quite a big effort to explain what I am looking for in the comments to the other answers.
-1

If you want to check that the output of x.cgi is properly formatted HTML/XHTML/XML/etc, why not run it through the W3 Validator?

You can download the source and find some way to call it from your Perl test script. Or, you might able to leverage this Perl interface to calling the W3 Validator on the web.

1 Comment

That's a nice suggestion but I am interested in the HTTP headers, which that won't work for.
-1

If you want to write a testing framework, I'd suggest taking a look at Test::More from CPAN as a good starting point. It's powerful but fairly easy to use and is definitely going to be better than cobbling something together as a one-off.

1 Comment

Thanks that is a good suggestion and I already use Test::More, but I am looking for something specifically for the HTTP headers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.