Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

petdance (2468)

AOL IM: petdance (Add Buddy, Send Message)
Yahoo! ID: petdance (Add User, Send Message)

I'm Andy Lester, and I like to test stuff. I also write for the Perl Journal, and do tech edits on books. Sometimes I write code, too.

Journal of petdance (2468)

Tuesday April 20, 2004
03:34 PM

WWW::Mechanize subclassing to help tests

[ #18411 ]
We do plenty of web app testing using WWW::Mechanize. A typical .t file will look like:

use WWW::Mechanize;
use Test::HTML::Lint;

my $startURL = $ENV{TWSMOKESERVER} or die "TWSMOKESERVER not set";

my $agent = WWW::Mechanize->new();
$agent->get( "$startURL/about_reading_programs.html" );
ok( $agent->success, 'got a page' );
like( $agent->title, qr/Reading Management Programs/, 'about reading programs page title' );

html_ok( $agent->content, 'about reading programs page HTML' );

So now we've started using a subclass, TW::Mechanize (TW is our app).

use TW::Mechanize;

my $startURL = $ENV{TWSMOKESERVER} or die "TWSMOKESERVER not set";

my $agent = TW::Mechanize->new();
# make sure we get the about-reading-programs page
$agent->get( "$startURL/about_reading_programs.html" );
ok( $agent->success, 'got a page' );
$agent->title_like( qr/Reading Management Programs/, 'about reading programs page title' );
$agent->html_ok( 'about reading programs page HTML' );

At some point, we'll probably make that html_ok call part of every call that gets made.

Here's what TW::Mechanize looks like:

package TW::Mechanize;

use strict;
use warnings;
use WWW::Mechanize;
use Test::More;

use base qw( WWW::Mechanize );

=head1 NAME

TW::Mechanize - The TW-specific mech subclass


    use TW::Mechanize;

    my $mech = TW::Mechanize->new;
    $mech->get( $url );


The TW mech is a standard WWW::Mechanize, with TW-specific methods added.

=head1 METHODS

=head2 new

Standard Mech constructor.


sub new {
    my $class = shift;

    my %default_args = (
        # None yet
    my $self = $class->SUPER::new( %default_args, @_ );

    return $self;

=head2 html_ok( [$msg] )

Checks the validity of the HTML on the current page.  If the page is
not HTML, then it fails.


sub html_ok {
    my $self = shift;
    my $msg = shift;

    my $ok;

    if ( $self->is_html ) {
        require Test::HTML::Lint;
        $ok = Test::HTML::Lint::html_ok( $self->content, $msg );
    } else {
        $ok = fail( $msg );

    return $ok;

=head2 title_is( $str [, $msg ] )

Tells if the title of the page is the given string.


sub title_is {
    my $self = shift;
    my $str = shift;
    my $msg = shift;

    return is( $self->title, $str, $msg );

=head2 title_like( $regex [, $msg ] )

Tells if the title of the page matches the given regex


sub title_like {
    my $self = shift;
    my $regex = shift;
    my $msg = shift;

    return like( $self->title, $regex, $msg );

1; # Happy

We could put autocheck => 1 as a default parm in the constructor and not have to check success any more, too....

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • If you only want to add new methods, you could decorate WWW::Mech rather than subclass it. Just add methods to WWW::Mech from TW::Mech since it does not have to actually be the package TW::Mech.

    At some point, it looks like you will have Mech doing everything. :)
  • Looks like Test::Mechanize would be a good addition to the WWW::Mechanize distribution. :-)


    • Well, don't think I haven't thought about it. :-)

      I don't see it being a Test:: module, but maybe so. It wouldn't be part of Mech proper, because it would bring in too many requirements, and Mech is fat enough as is.

      It's certainly an idea rolling around in my head....