Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Tests for CGI apps

by jest (Pilgrim)
on Nov 18, 2003 at 18:58 UTC ( #308076=perlquestion: print w/replies, xml ) Need Help??

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

I'm starting to have difficulty testing my apps by seat-of-the-pants methods, and figured it's about time to start learning how to use proper tests in Perl. I've looked at various docs, including the Test::Tutorial POD, and Test::Simple and Test::More, and some other Perlmonks threads that didn't really cover this.

What I'm not grasping is how one would use these in a CGI enviroment, esp. with backend database access as well. If, in order to do the most basic test, I need to set/read cookies, retrieve session info and user access levels from a DB, and that sort of thing, it seems like it would be really hard to do. And that doesn't even consider testing an app that generates forms and then processes/returns results from a database, or, worse, testing something that adds data to a database.

I suppose one could use something like WWW::Mechanize to perform tests on running CGI apps, but this seems like a different thing than creating and running a test suite.

My immediate inspiration is that I have a search function that allows a user to search on various fields, and after running with no problems for some time, I got a failure because one of the lesser-used fields had an improper verification routine attached to it, and it took a long time before someone chanced to enter just the right improper value to trigger the failure. But I couldn't figure out how to create a non-manual test for this.

Replies are listed 'Best First'.
•Re: Tests for CGI apps
by merlyn (Sage) on Nov 18, 2003 at 19:12 UTC
    Hopefully, you've separated your Model code from your View code and your Controller code.

    You can test your Model code using Test::* modules.

    You can test your View code by simulating your Controller code and matching the web output captured as a string. Hopefully, you're smart enough to return strings rather than "print" everything. {grin}

    Once those are verified, you can test your Controller code by firing up your app on a mini-server, and poking at it with WWW::Mechanize, driven by a Test::* script.

    Yes, it takes more work to design a web app that is testable, but the consequences of not testing are clearly documented.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: Tests for CGI apps
by hardburn (Abbot) on Nov 18, 2003 at 19:17 UTC

    This is the very problem I aim to solve (at least in part) with HTML::Template::Dumper. I imagine a system that works this way:

    1. A machine in your office runs a daily cron job which points to a directory containing your test scripts
    2. To start the process, the test scripts has your web server create a file at /tmp/debug_mode, which allows your CGIs to take a DEBUG=1 parameter, which in turn causes them to use the HTML::Template::Dumper module (among other things you might want to use in debug mode
    3. Your test scripts use LWP to send various parameters to your CGIs. Normal rules about tests apply here. Using HTML::Template::Dumper means that checking the output from your CGI is as easy as walking a hash.
    4. After all the tests run, the web server is told to get rid of the /tmp/debug_mode file so that CGIs will no longer allow a DEBUG parameter
    5. A final report is sent to the web master and/or saved in a database

    The /tmp/debug_mode file means you could run the tests against your production web server with debug mode only allowed for a limited period of time. You probably don't want debugging information leaking out on a regular basis (though for many CGIs, it will probably be little more than would be filled into a template anyway). More sophisticated cryptographic techniques for turning on debug mode are also possible, if you're really concerned about security.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

Re: Tests for CGI apps
by perrin (Chancellor) on Nov 18, 2003 at 20:33 UTC
    The advice from merlyn about testing the different parts of the app separately is good. For the actual controller part, if you're using CGI::Application, I found the approach described here worked very well for me. Otherwise, Mechanize is a good choice. You will have to include some setup to put fake data into your database. This sounds like a lot of work, but it's really worth it to have piece of mind. WIth a good set of tests, you can instantly tell if your code is still working after you make a change somewhere.

      Thanks for the various ideas.

      I regret that I have not, thus far, cleanly separated my M from my C, though my V is nicely off in TT. But I can probably adopt some form of mixing Test::* tests with a WWW::Mechanize implementation. Hope this isn't too time-consuming to implement....

        Hope this isn't too time-consuming to implement...

        If you're planning to maintain and develop your code base it'll be worth it no matter how long it takes.

        You'll eventually find yourself modifying your application so it's easier to write tests for.. this is a good thing. It'll probably mean you're making your code more modular which will in turn make it easier to develop.

        oh, and you'll know it was all worth it when you make a quick and simple change which "won't affect anything else" and your test suite finds and identifies a bug in 10 seconds..

        I've spent a lotta time writing tests and improving my app to make it testable over the last 6 months, but I still don't think I've come close to the amount of time I've saved compared to manual testing and searching for bugs...

        cheers,

        J

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://308076]
Approved by valdez
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (1)
As of 2022-01-29 14:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:












    Results (74 votes). Check out past polls.

    Notices?