WWW::Mechanize and the values of testing
20 Dec 2006One of the great things about going to LISA is that you get the proceedings and/or training for everything on CD or dead tree. (Well, nearly everything...I've heard that some people didn't or couldn't make their training materials available (though I've not been motivated to confirm this yet), and some of the talks didn't do this (Tom, where are your slides?)). There is some wonderful stuff to be found in them...
...like WWW::Mechanize, which is just perfect for testing out this conference registration form I'm working on. Only I've run into a bug that comes when trying to specify which button to click on:
$agent->click_button(value => 'Okay to submit');
That li'l chunk gave me this error:
Can't call method "header" on an undefined value at /home/admin/hugh/perl/lib/perl5/WWW/Mechanize.pm line 2003.
One guy reported the same trouble, but got no response. And the RT queue is fulla spam.
But aha, I found out how to use the Perl debugger in Emacs (M-x
perldb
. Shhhh!) and was able to track things down. Turns out there
are a couple things going on:
In the page that I'm parsing, there are actually two forms, not one; one sends you back to correct mistakes, one sends you forward to keep going. Since I was not specifying which one to use, it used the first...and in that one, there is no button labelled "Okay to submit". Once I specified the right form (
$agent->form_number(2);
) everything was good.But of course, this sort of thing shouldn't happen, right? Right.
There are a couple subroutines/methods in this module that aren't
testing for the right number of arguments. One of 'em is
click_button
, which has this loop:
my $request;
.
.
.
elsif ( $args{value} ) {
my $i = 1;
while ( my $input = $form->find_input(undef, 'submit', $i) ) {
if ( $args{value} && ($args{value} eq $input->value) ) {
$request = $input->click( $form, $args{x}, $args{y} );
last;
}
$i++;
} # while
} # $args{value}
return $self->request( $request );
No test/case for not finding a button named whatever, so it just
blithely returns $self->request( $request )
. But of course,
request
does the same thing:
sub request {
my $self = shift;
my $request = shift;
$request = $self->_modify_request( $request );
if ( $request->method eq "GET" || $request->method eq "POST" ) {
$self->_push_page_stack();
}
$self->_update_page($request, $self->_make_request( $request, @_ ));
}
Again, no test for the right number of arguments. And having just read
the Test::Tutorial
manpage, I'm all about unit testing and such,
baby.
2 Comments
From: chris
20-December-2006-14:01:08
I read with interest your travails at LISA. My repressed academic/fanboy is proud to know you (if somewhat envious).
Good job on the debugging, but please be careful with Perl, as it has brought many a stalwart hacker to the verge of breakdown. I propose a new Perl motto: Brought To You By Pixies On Crystal Meth.
From: Saint Aardvark
20-December-2006-14:17:47
Brought To You By Pixies On Crystal Meth...dude, I may start adding that to source code right after the GPL.
Add a comment:
Name and email required; email is not displayed.
Related Posts
QRP weekend 08 Oct 2018
Open Source Cubesat Workshop 2018 03 Oct 2018
mpd crash? try removing files in /var/lib/mpd/ 11 Aug 2018