fenLisesi has asked for the wisdom of the Perl Monks concerning the following question:
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:
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:${ $mech->{form}{action} } =~ s{ \.pl \z}{_del.pl}x;
At any rate, I would appreciate some web application testing advice.my $action = $mech->current_form()->action(); $action =~ s{ \.pl \z}{_del.pl}x; $mech->current_form()->action( $action );
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:
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.## 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);
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 | |
by adrianh (Chancellor) on Apr 14, 2007 at 22:24 UTC | |
by Your Mother (Archbishop) on Nov 16, 2007 at 20:12 UTC | |
by dragonchild (Archbishop) on Nov 16, 2007 at 20:36 UTC |