http://www.perlmonks.org?node_id=846191

Still being something of a newbie (AKA the more I know, the more I realize how little I know), I got a bit stuck recently whilst trying to write some test scripts for uploading an image to a CGI::Application web page. So I had a look at the test scripts for CGI. It's all pretty much laid out in http://cpansearch.perl.org/src/LDS/CGI.pm-3.49/t/upload.t. This script first sets various environment variables, and then localizes the STDIN, feeds a MIME formatted file into the STDIN and then finally creates a CGI object, which then of course reads the environment variables and the STDIN.

I thought to myself there has to be a better way. I propose to shamelessly rip out the guts of that test script and turn it into a more reusable Test module. I was thinking of calling it "Test::CGI::POST". Although in the Test namespace it would not be a standard test module with ever more esoteric "ok_...." methods. Rather I was thinking of the following more OO interface:

  1. As a convenience when you do "use Test::CGI::POST" you can specify some environment variables. There could also be some options for standard sets of environment variables.
  2. The constructor would take a CODE ref that must return a CGI like object. This CODE ref could be changed later but the module is useless without it so it might as well either be mandatory in the constructor or at least default to returning a plain CGI object.
  3. There would be a "param" method with much the same options as CGI::param.
  4. The key method would be the "create_cgi" method. It would do the trick of tweaking the STDIN, formatting the stashed parameters from the "param" method into a MIME stream and feeding that into STDIN, before calling the create CGI callback, the result of which would be returned.
  5. There could also be some helper methods based upon GD for creating an image of a specified format, width and height.

Edit: I have started work on this at http://github.com/periapt/Test-CGI-Multipart. Nothing useable so far but as a proof of concept it is there.

Replies are listed 'Best First'.
Re: RFC: Systemizing CGI upload testing
by GrandFather (Saint) on Jun 24, 2010 at 10:46 UTC

    Maybe you are thinking in the direction of a Test::Mock::CGI module along the lines of Test::MockObject?

    True laziness is hard work
      No. Test::MockObject is essential if you are trying to achieve complete test coverage of a module - for example where you are trying to simulate unusual behaviour such as database queries failing for no particular reason. Rather the behaviour I am seeking to simulate is the normal behaviour of web server when processing a POST request - without actually running a web server.

        But doesn't that come to much the same thing? I use MockObject most often to mock MIME::Lite so that the code I'm testing thinks it is doing business as usual, but I can capture and print locally the email that would have been sent - not unlike your non-running web server really.

        True laziness is hard work