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

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

O wise ones,

For the last few days, I have been writing tests for a typical RDBMS-backend, web-frontend, Perl-in-the-middle application. One of the main tools in my arsenal has been WWW::Mechanize.

The typical delete-item use case has been implemented with a little Javascript. The Delete button has an onClick attribute, which changes the action of the form. For example, the default action could be camels.pl and the Delete button would change this to camels_del.pl before submitting it.

Since WWW::Mechanize doesn't care about Javascript, and my half-hour attempt at installing Mozilla::Mechanize got stuck at a few Gtk2 test failures, I thought the best course of action would then be to "manually" change the action of the form.

I browsed the source for WWW::Mechanize and its ancestors a bit (<heavenly-voice>use the source, luke</heavenly-voice>) -- and Data::Dumper::Dumper'ed the form -- to end up with this hold-your-mutable-internal-organs-and-twist-them move:

${ $mech->{form}{action} } =~ s{ \.pl \z}{_del.pl}x;
Aaand, chalk up another one for talk-to-your-teddy-bear. I just looked at the docs again (<homer>stupid heavenly-voice!</homer>) and saw that the following straightforward snippet is possible:
my $action = $mech->current_form()->action(); $action =~ s{ \.pl \z}{_del.pl}x; $mech->current_form()->action( $action );
At any rate, I would appreciate some web application testing advice.

While I am at it, here is a pet peeve: If you set up your test code in OO fashion, then use'ing Test::* modules both in the ancestor and in the child causes problems due to multiple plans. The right way seems to be to, for example, use Test::More, in the ancestor, have all your ok(...)'s in that ancestor module inside subs like num_checkboxes_is(...), then call those subs from the descendants. Perhaps that's better anyway, as it keeps all the ok(...) and friends toghether there.

I wrote some unit tests last year using Test::Class and that was nice, smooth sailing.

Coming back to WWW::Mechanize again, I find myself doing things like:

## create an HTML::TreeBuilder obj from the content my $tree = $self->gen_tree( $mech->content() ); ## see if there are exactly 10 camel_id checkboxes $self->check_for_input( $tree, sub { my ($widget) = @_; if (lc( $widget->attr('type') ) eq 'checkbox' and $widget->attr('name') eq 'camel_id') { return 1; } return; }, 'Camel checkboxes', 10);
where gen_tree returns an instance of HTML::TreeBuilder and check_for_input(...), implemented in the base class, uses look_down(). I do this because I have used HTML::TreeBuilder before and look_down() is a simple concept.

Since $mech already has all the structure of the document, though, it seems to be a waste to generate another big tree just because look_down() is flexible and simple. I have thus far ignored this waste, because, I don't care so much whether the smoke tests run between 3am and 4am or between 3am and 4:30am.

Test::WWW::Mechanize looks like the go-to guy in 4 cases out of 5, but a quick look at the docs gave me the (probably false) impression that it did not have the flexibility of look_down().

Replies are listed 'Best First'.
Re: General web application testing advice sought.
by dragonchild (Archbishop) on Apr 13, 2007 at 17:18 UTC
    If you can, take a look at Selenium. It's phenomenal and the guys who run it are easy to work with.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      I second that recommendation. Hell, the IDE will even go generate the Perl for you :-)

      Holy crap that's hot. You know, I don't know what's wrong with me. I've seen Selenium mentioned before, here and other places, and for some reason I just assumed it wouldn't run on my stuff or it was Windows or a lot of trouble or a partial solution or... I never checked it out till now. Stupid, stupid me. Selenium is easily the best thing I've seen in two years. This plus Firebug means dynamic web dev work has lost about 95% of its voodoo.

        Have you checked out Test::WWW::Selenium? :-)

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?