Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Web testing without the web server.

by kyle (Abbot)
on Mar 27, 2009 at 15:53 UTC ( [id://753696]=perlquestion: print w/replies, xml ) Need Help??

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

I have the opportunity to write a web application from scratch, and I really want it to be as testable as possible, and I'd like to hear from the monks about how to do that.

What I'd really like to avoid is some variant on full blown web client to web server communication for testing. I don't want to write Selenium scripts (though I might, just to check the templates), and I don't want to spawn a baby web server when I'm testing (though a baby database doesn't bother me).

The approach I'm considering right now is to write the controllers with an interface that simply takes CGI-ish parameters and returns data ready for the Template. So: data structure in, data structure out.

The actual Catalyst controller can then be a thin wrapper around these testable components.

I see that CGI has a save() method, and it can load its save files, but it appears those save files don't include things from the environment like the remote IP address, browser's user agent string, or other things I might want to use to taylor content. Because of this, I think I need to do more work to "mock" parameters to a controller. Just creating a new CGI object from passed in parameters isn't enough.

Has anyone else out there faced this, written this, done this? Is there an article on the best way to go about what I'm talking about? I have the chance to do this right from the start, so any ideas would be welcome!

Replies are listed 'Best First'.
Re: Web testing without the web server.
by Your Mother (Archbishop) on Mar 27, 2009 at 16:38 UTC

    You can't exactly do that. When you test a web application you're testing its responses to GET/HEAD/POST/ETC and that it responds to them correctly with good headers etc. To test web applications you necessarily have to test the transport layer with it and doing that without a webserver of some kind implies writing code that would mimic a webserver's behavior which is goofy (well, not goofy but why we have the stuff Corion mentioned).

    I understand your goal though -- it's the unit versus app test problem -- and Catalyst::Controller::REST might fit (part of) the bill. It can be set up so that accept headers dictate how the response is returned. So your tests, for example, could say they'll only accept YAML and your controllers which serve nice XHTML for browsers (which say they accept it) would serve the same stash data that builds the template as YAML instead.

    I think in the end though you really have to test the web app directly, your underlying code is stuff like DBI.pm and URI.pm which is well tested already, and if you have JS you'd best use Selenium (which writes 90% of the tests automatically) so starting with a pure unit/in:out testing approach might only (probably will, I'd say) end up duplicating work and making tests redundant.

      I like the Catalyst::Controller::REST idea. Thanks!

      I'm expecting my views to be pretty simple. I doubt there will be a lot of including of other templates or flow control beyond a little looping. As such, I'm not as concerned about checking that my (simple) templates work, that template toolkit renders them correctly, etc. Basically, when the controller is done, I think most of my code's work is done.

      I can test the models with little more than data structures in and data structures out. I want to test the other components that way too!

      Of course, wanting it doesn't make it possible. You may be right, and I may be trying to ignore an important part of testing. Thanks for your thoughts!

Re: Web testing without the web server.
by Corion (Patriarch) on Mar 27, 2009 at 16:02 UTC

      Those are some really good testing tools (I say, not having used them much), but this is a lot like what I'm trying to avoid. Unless I'm missing something, these go through an entire request process with a given URL and then scrape the HTML that results. While it's important to get the HTML (view) right, I want to keep that separate from checking the functionality of the underlying controller (which is what interests me a lot more).

Re: Web testing without the web server.
by tilly (Archbishop) on Mar 27, 2009 at 17:31 UTC
    If Catalyst::Test is unable to do what you want, I'd suggest extending that instead of starting from scratch. It looks to me like you should be able to set anything you want by setting %ENV before calling it, but do test that.

    You may also find Configuring Catalyst's Makefile.PL? relevant as you're trying to set things up.

      It looks to me as if Catalyst::Test will work for me.

      # HTTP::Response & context object my($res, $c) = ctx_request('index.html');

      If I understand this right, I get the response and context object as they were when the request finished. As such, I can dig in and get the parameters that were passed to the template, the HTML content, headers, etc. That's excellent!

        That is correct. However be warned that out of the box it does not let you easily set things like remote IP addresses and cookies when you construct a request.
Re: Web testing without the web server.
by jdrago_999 (Hermit) on Mar 27, 2009 at 19:03 UTC
Re: Web testing without the web server.
by kubrat (Scribe) on Mar 30, 2009 at 10:57 UTC
    If your main motivation for wanting to test your web app this way is the unit versus app problem as Your_Mother pointed out then it is fine. But it is not fine if you are simply trying to avoid running a web server. Unless you are stress testing running a web server or a database server is not an issue for any desktop machine.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (7)
As of 2024-04-24 10:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found