[Jifty-commit] r4361 - in Test-WWW-Declare: lib/Test/WWW
lib/Test/WWW/Declare t
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Fri Nov 2 14:52:31 EDT 2007
Author: sartak
Date: Fri Nov 2 14:52:31 2007
New Revision: 4361
Modified:
Test-WWW-Declare/ (props changed)
Test-WWW-Declare/META.yml
Test-WWW-Declare/Makefile.PL
Test-WWW-Declare/README
Test-WWW-Declare/lib/Test/WWW/Declare.pm
Test-WWW-Declare/lib/Test/WWW/Declare/Tester.pm
Test-WWW-Declare/t/07-alt-names.t
Test-WWW-Declare/t/08-error.t
Log:
r43126 at onn: sartak | 2007-09-26 16:30:38 -0400
Various cleanups and doc
Modified: Test-WWW-Declare/META.yml
==============================================================================
--- Test-WWW-Declare/META.yml (original)
+++ Test-WWW-Declare/META.yml Fri Nov 2 14:52:31 2007
@@ -1,4 +1,6 @@
---
+abstract: ~
+author: Best Practical Solutions, LLC
build_requires:
HTTP::Server::Simple::CGI: 0
Test::Tester: 0
Modified: Test-WWW-Declare/Makefile.PL
==============================================================================
--- Test-WWW-Declare/Makefile.PL (original)
+++ Test-WWW-Declare/Makefile.PL Fri Nov 2 14:52:31 2007
@@ -1,8 +1,7 @@
use inc::Module::Install;
-name 'Test-WWW-Declare';
-license 'perl';
-version_from 'lib/Test/WWW/Declare.pm';
+name 'Test-WWW-Declare';
+all_from 'lib/Test/WWW/Declare.pm';
build_requires 'Test::Tester';
build_requires 'HTTP::Server::Simple::CGI';
Modified: Test-WWW-Declare/README
==============================================================================
--- Test-WWW-Declare/README (original)
+++ Test-WWW-Declare/README Fri Nov 2 14:52:31 2007
@@ -1 +1,119 @@
-This is only a prototype. If this were an actual distribution, there would be tests and docs. To say nothing of full functionality.
+SYNOPSIS
+ use Test::WWW::Declare tests => 3;
+ use Your::Web::App::Test;
+
+ Your::Web::App::Test->start_server;
+
+ session 'testuser' => run {
+ flow 'log in and out' => check {
+ flow 'log in' => check {
+ get 'http://localhost/';
+ fill form 'login' => {
+ username => 'testuser',
+ password => 'drowssap',
+ };
+ content should contain 'log out';
+ };
+
+ flow 'log out' => check {
+ get 'http://localhost/';
+ click href 'log out';
+ };
+ };
+ };
+
+DESCRIPTION
+ Often in web apps, tests are very dependent on the state set up by
+ previous tests. If one test fails (e.g. "follow the link to the admin
+ page") then it's likely there will be many more failures. This module
+ aims to alleviate this problem, as well as provide a nicer interface to
+ Test::WWW::Mechanize.
+
+ The central idea is that of "flow". Each flow is a sequence of commands
+ ("fill in this form") and assertions ("content should contain
+ 'testuser'"). If any of these commands or assertions fail then the flow
+ is aborted. Only that one failure is reported to the test harness and
+ user. Flows may also contain other flows. If an inner flow fails, then
+ the outer flow fails as well.
+
+FLOWS AND SESSIONS
+ session NAME => run { CODE }
+ Sessions are a way of associating a set of flows with a WWWW::Mechanize
+ instance. A session is mostly equivalent with a user interacting with
+ your web app.
+
+ Within a session, every command ("get", "click link", etc) is operating
+ on that session's WWW::Mechanize instance. You may have multiple
+ sessions in one test file. Two sessions with the same name are in fact
+ the same session. This lets you write code like the following,
+ simplified slightly:
+
+ session 'first user' => run {
+ get "$URL/give?task=1&victim=other";
+ session 'other user' => run {
+ get "$URL/tasks";
+ content should match qr/task 1/;
+
+ # this is the same session/mech as the outermost 'first user'
+ session 'first user' => run {
+ get "$URL/tasks";
+ content shouldnt match qr/task 1/;
+ };
+ };
+ };
+
+ flow NAME => check { CODE }
+ A flow encompasses a single test. As described above, each flow is a
+ sequence of commands, assertions, and other flows. If any of the
+ components of a flow fail, the rest of the flow is aborted and one or
+ more test failures are reported to the test harness.
+
+COMMANDS
+ get URL
+ click button
+ click href
+ follow_link
+ fill form NAME => {FIELD1 => VALUE1, FIELD2 => VALUE2}
+ASSERTIONS
+ Every assertion has two parts: a subject and a verb.
+
+ SUBJECTS
+ content
+ title
+ url
+ VERBS
+ should(nt) (caselessly) match REGEX
+ should(nt) (caselessly) contain STRING
+ should(nt) (caselessly) lack STRING
+ should(nt) (caselessly) equal STRING
+SUBCLASSING
+ One of the goals of this module is to let you subclass it to provide
+ extra features, such as automatically logging in a user each time a
+ session is created.
+
+CAVEATS
+ If you fail any tests, then the actual number of tests run may be fewer
+ than you have in your file. This is because when a flow fails, it
+ immediately aborts the rest of its body (which may include other flows).
+ So if you're setting the number of tests based on how many ran, make
+ sure that all tests passed.
+
+BUGS
+ Hopefully few. We'd like to know about any of them. Please report them
+ to "bug-test-www-declare at rt.cpan.org".
+
+SEE ALSO
+ Test::WWW::Mechanize, Jifty.
+
+MAINTAINER
+ Shawn M Moore "<sartak at bestpractical.com>"
+
+ORIGINAL AUTHOR
+ Jesse Vincent "<jesse at bestpractical.com>"
+
+COPYRIGHT
+ Copyright 2007 Best Practical Solutions, LLC
+
+ This program is free software; you can redistribute it and/or modify it
+ under the same terms as Perl itself.
+
Modified: Test-WWW-Declare/lib/Test/WWW/Declare.pm
==============================================================================
--- Test-WWW-Declare/lib/Test/WWW/Declare.pm (original)
+++ Test-WWW-Declare/lib/Test/WWW/Declare.pm Fri Nov 2 14:52:31 2007
@@ -37,11 +37,13 @@
use Test::WWW::Declare tests => 3;
use Your::Web::App::Test;
+ Your::Web::App::Test->start_server;
+
session 'testuser' => run {
flow 'log in and out' => check {
flow 'log in' => check {
get 'http://localhost/';
- fill form 'login' => check {
+ fill form 'login' => {
username => 'testuser',
password => 'drowssap',
};
@@ -357,7 +359,12 @@
my $form_name = shift;
my $data = shift;
- mech()->form_name($form_name);
+ my $form = mech()->form_name($form_name);
+
+ if (!defined($form)) {
+ Carp::croak "There is no form named '$form_name'";
+ }
+
return $data;
}
@@ -397,7 +404,10 @@
$BUILDER->ok(0, $name);
- if ($@ !~ /^Flow '/) { # failure occurred during outermost flow
+ if ($@ =~ /^Flow '/) {
+ $BUILDER->diag($@);
+ }
+ else {
$BUILDER->diag("Flow '$name' failed: $@");
}
}
@@ -410,7 +420,7 @@
my $title = shift;
my $coderef = shift;
- $mechs{$title} ||= Test::WWW::Mechanize->new();
+ $mechs{$title} ||= Test::WWW::Mechanize->new(quiet => 1);
local $WWW_MECHANIZE = $mechs{$title};
$coderef->();
@@ -419,23 +429,59 @@
my $reason = $1;
$BUILDER->skip($reason);
}
+ elsif ($@ =~ /^Flow '/) {
+ # flow already displayed the error
+ }
elsif ($@) {
$BUILDER->diag($@);
}
}
-# miscellaneous
-# I find myself constantly wanting to dump mech content to a file during
-# testing for diagnosis, so make it easy here: dump to 'mech.html';
sub dump($) {
my $file = shift;
- open my $handle, '>', $file or die "Unable to open $file for writing: $!";
- print $handle mech->content;
- close $handle;
+ mech->save_content($file);
}
# used only for testing that we got T:W:D's goods
sub _twd_dummy { "XYZZY" }
+=head1 SUBCLASSING
+
+One of the goals of this module is to let you subclass it to provide extra
+features, such as automatically logging in a user each time a session is
+created.
+
+=head1 CAVEATS
+
+If you fail any tests, then the actual number of tests run may be fewer than
+you have in your file. This is because when a flow fails, it immediately aborts
+the rest of its body (which may include other flows). So if you're setting the
+number of tests based on how many ran, make sure that all tests passed.
+
+=head1 BUGS
+
+Hopefully few. We'd like to know about any of them. Please report them to
+C<bug-test-www-declare at rt.cpan.org>.
+
+=head1 SEE ALSO
+
+L<Test::WWW::Mechanize>, L<Jifty>.
+
+=head1 MAINTAINER
+
+Shawn M Moore C<< <sartak at bestpractical.com> >>
+
+=head1 ORIGINAL AUTHOR
+
+Jesse Vincent C<< <jesse at bestpractical.com> >>
+
+=head1 COPYRIGHT
+
+Copyright 2007 Best Practical Solutions, LLC
+
+This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+
+=cut
+
1;
Modified: Test-WWW-Declare/lib/Test/WWW/Declare/Tester.pm
==============================================================================
--- Test-WWW-Declare/lib/Test/WWW/Declare/Tester.pm (original)
+++ Test-WWW-Declare/lib/Test/WWW/Declare/Tester.pm Fri Nov 2 14:52:31 2007
@@ -95,7 +95,7 @@
use Test::WWW::Declare;
use base 'Test::More';
-our $VERSION = '0.00';
+our $VERSION = '0.01_01';
our @EXPORT = qw($PORT $SERVER $PID);
our $PORT = 12321;
Modified: Test-WWW-Declare/t/07-alt-names.t
==============================================================================
--- Test-WWW-Declare/t/07-alt-names.t (original)
+++ Test-WWW-Declare/t/07-alt-names.t Fri Nov 2 14:52:31 2007
@@ -16,6 +16,9 @@
title contains 'DEX';
title never contains 'dEX';
title contains caselessly 'dEX';
+
+ content shouldnt equal 'anything this short';
+ content shouldnt match qr/HELLO CPAN/;
};
};
}
Modified: Test-WWW-Declare/t/08-error.t
==============================================================================
--- Test-WWW-Declare/t/08-error.t (original)
+++ Test-WWW-Declare/t/08-error.t Fri Nov 2 14:52:31 2007
@@ -1,24 +1,33 @@
#!perl
-use Test::WWW::Declare::Tester tests => 4;
+use Test::WWW::Declare::Tester tests => 7;
use warnings;
use strict;
my @results = run_tests(
sub {
session "check logins" => run {
- flow "basic connectivity" => check {
+ flow "click href expects a regex" => check {
get "http://localhost:$PORT/";
click href 3;
};
+ flow "no form foo" => check {
+ fill form foo => {
+ true => 'false',
+ false => 'true',
+ };
+ };
};
}
);
shift @results; # Test::Tester gives 1-based arrays
-is(@results, 1, "had two tests");
+is(@results, 2, "had two tests");
ok(!$results[0]{ok}, "1st test passed");
+ok(!$results[1]{ok}, "2nd test passed");
-is($results[0]{name}, "basic connectivity", "1st test was flow");
+is($results[0]{name}, "click href expects a regex");
+is($results[1]{name}, "no form foo");
-like($results[0]{diag}, qr/click doesn\'t know what to do with a link type of at/, 'reasonable error message for "click href 3"');
+like($results[0]{diag}, qr/click doesn\'t know what to do with a link type of at/, 'reasonable error message for "click href 3"');
+like($results[1]{diag}, qr/Flow 'no form foo' failed: There is no form named 'foo'/, 'reasonable error message for "fill form nonexistent"');
More information about the Jifty-commit
mailing list