X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Manual.git;a=blobdiff_plain;f=lib%2FCatalyst%2FManual%2FTutorial%2FTutorial%2FTesting.pod;fp=lib%2FCatalyst%2FManual%2FTutorial%2FTutorial%2FTesting.pod;h=0000000000000000000000000000000000000000;hp=f3b2b6412e68a293ba60971f1dea7e2f5762d3ac;hb=5e6026272f809951ac22fae43b73d2c1dc79c7fc;hpb=d442cc9fbdf45a28fe02f13552f44e3e2f7ec22e diff --git a/lib/Catalyst/Manual/Tutorial/Tutorial/Testing.pod b/lib/Catalyst/Manual/Tutorial/Tutorial/Testing.pod deleted file mode 100644 index f3b2b64..0000000 --- a/lib/Catalyst/Manual/Tutorial/Tutorial/Testing.pod +++ /dev/null @@ -1,351 +0,0 @@ -=head1 NAME - -Catalyst::Manual::Tutorial::Testing - Catalyst Tutorial - Part 7: Testing - - -=head1 OVERVIEW - -This is B for the Catalyst tutorial. - -L - -=over 4 - -=item 1 - -L - -=item 2 - -L - -=item 3 - -L - -=item 4 - -L - -=item 5 - -L - -=item 6 - -L - -=item 7 - -B - -=item 8 - -L - -=item 9 - -L - -=back - -=head1 DESCRIPTION - -You may have noticed that the Catalyst Helper scripts automatically -create basic C<.t> test scripts under the C directory. This part of -the tutorial briefly looks at how these tests can be used to not only -ensure that your application is working correctly at the present time, -but also provide automated regression testing as you upgrade various -pieces of your application over time. - -You can checkout the source code for this example from the catalyst -subversion repository as per the instructions in -L - -=head1 RUNNING THE "CANNED" CATALYST TESTS - -There are a variety of ways to run Catalyst and Perl tests (for example, -C and C), but one of the easiest is with the -C command. For example, to run all of the tests in the C -directory, enter: - - $ prove --lib lib t - -The redirection used by the Authentication plugins will cause the -default C to fail. You can fix this by changing the line in -C that read: - - ok( request('/')->is_success, 'Request should succeed' ); - -to: - - ok( request('/login')->is_success, 'Request should succeed' ); - -So that a redirect is not necessary. Also, the C -and C default test cases will fail because of the -authorization. You can delete these two files to prevent false error -messages: - - $ rm t/controller_Books.t - $ rm t/controller_Logout.t - -As you can see in the C command line above, the C<--lib> option -is used to set the location of the Catalyst C directory. With this -command, you will get all of the usual development server debug output, -something most people prefer to disable while running tests cases. -Although you can edit the C to comment out the C<-Debug> -plugin, it's generally easier to simply set the C -environment variable. For example: - - $ CATALYST_DEBUG=0 prove --lib lib t - -During the C and C tests, you might notice the -C warning message. To -execute the Pod-related tests, add C to the C -command: - - $ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib t - -If you omitted the Pod comments from any of the methods that were -inserted, you might have to go back and fix them to get these tests to -pass. :-) - -Another useful option is the C (C<-v>) option to C. It -prints the name of each test case as it is being run: - - $ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib -v t - -=head1 RUNNING A SINGLE TEST - -You can also run a single script by appending its name to the C -command. For example: - - $ CATALYST_DEBUG=0 prove --lib lib t/01app.t - -Note that you can also run tests directly from Perl without C. -For example: - - $ CATALYST_DEBUG=0 perl -Ilib t/01app.t - -=head1 ADDING YOUR OWN TEST SCRIPT - -Although the Catalyst helper scripts provide a basic level of checks -"for free," testing can become significantly more helpful when you write -your own script to exercise the various parts of your application. The -L module -is very popular for writing these sorts of test cases. This module -extends L (and therefore -L) to allow you to automate the action of -a user "clicking around" inside your application. It gives you all the -benefits of testing on a live system without the messiness of having to -use an actual web server, and a real person to do the clicking. - -To create a sample test case, open the C file in your -editor and enter the following: - - #!/usr/bin/perl - - use strict; - use warnings; - - # Load testing framework and use 'no_plan' to dynamically pick up - # all tests. Better to replace "'no_plan'" with "tests => 30" so it - # knows exactly how many tests need to be run (and will tell you if - # not), but 'no_plan' is nice for quick & dirty tests - - use Test::More 'no_plan'; - - # Need to specify the name of your app as arg on next line - # Can also do: - # use Test::WWW::Mechanize::Catalyst "MyApp"; - - use ok "Test::WWW::Mechanize::Catalyst" => "MyApp"; - - # Create two 'user agents' to simulate two different users ('test01' & 'test02') - my $ua1 = Test::WWW::Mechanize::Catalyst->new; - my $ua2 = Test::WWW::Mechanize::Catalyst->new; - - # Use a simplified for loop to do tests that are common to both users - # Use get_ok() to make sure we can hit the base URL - # Second arg = optional description of test (will be displayed for failed tests) - # Note that in test scripts you send everything to 'http://localhost' - $_->get_ok("http://localhost/", "Check redirect of base URL") for $ua1, $ua2; - # Use title_is() to check the contents of the ... tags - $_->title_is("Login", "Check for login title") for $ua1, $ua2; - # Use content_contains() to match on text in the html body - $_->content_contains("You need to log in to use this application", - "Check we are NOT logged in") for $ua1, $ua2; - - # Log in as each user - # Specify username and password on the URL - $ua1->get_ok("http://localhost/login?username=test01&password=mypass", "Login 'test01'"); - # Use the form for user 'test02'; note there is no description here - $ua2->submit_form( - fields => { - username => 'test02', - password => 'mypass', - }); - - # Go back to the login page and it should show that we are already logged in - $_->get_ok("http://localhost/login", "Return to '/login'") for $ua1, $ua2; - $_->title_is("Login", "Check for login page") for $ua1, $ua2; - $_->content_contains("Please Note: You are already logged in as ", - "Check we ARE logged in" ) for $ua1, $ua2; - - # 'Click' the 'Logout' link (see also 'text_regex' and 'url_regex' options) - $_->follow_link_ok({n => 1}, "Logout via first link on page") for $ua1, $ua2; - $_->title_is("Login", "Check for login title") for $ua1, $ua2; - $_->content_contains("You need to log in to use this application", - "Check we are NOT logged in") for $ua1, $ua2; - - # Log back in - $ua1->get_ok("http://localhost/login?username=test01&password=mypass", "Login 'test01'"); - $ua2->get_ok("http://localhost/login?username=test02&password=mypass", "Login 'test02'"); - # Should be at the Book List page... do some checks to confirm - $_->title_is("Book List", "Check for book list title") for $ua1, $ua2; - - $ua1->get_ok("http://localhost/books/list", "'test01' book list"); - $ua1->get_ok("http://localhost/login", "Login Page"); - $ua1->get_ok("http://localhost/books/list", "'test01' book list"); - - $_->content_contains("Book List", "Check for book list title") for $ua1, $ua2; - # Make sure the appropriate logout buttons are displayed - $_->content_contains("/logout\">Logout", - "Both users should have a 'User Logout'") for $ua1, $ua2; - $ua1->content_contains("/books/form_create\">Create", - "Only 'test01' should have a create link"); - - $ua1->get_ok("http://localhost/books/list", "View book list as 'test01'"); - - # User 'test01' should be able to create a book with the "formless create" URL - $ua1->get_ok("http://localhost/books/url_create/TestTitle/2/4", - "'test01' formless create"); - $ua1->title_is("Book Created", "Book created title"); - $ua1->content_contains("Added book 'TestTitle'", "Check title added OK"); - $ua1->content_contains("by 'Stevens'", "Check author added OK"); - $ua1->content_contains("with a rating of 2.", "Check rating added"); - # Try a regular expression to combine the previous 3 checks & account for whitespace - $ua1->content_like(qr/Added book 'TestTitle'\s+by 'Stevens'\s+with a rating of 2./, "Regex check"); - - # Make sure the new book shows in the list - $ua1->get_ok("http://localhost/books/list", "'test01' book list"); - $ua1->title_is("Book List", "Check logged in and at book list"); - $ua1->content_contains("Book List", "Book List page test"); - $ua1->content_contains("TestTitle", "Look for 'TestTitle'"); - - # Make sure the new book can be deleted - # Get all the Delete links on the list page - my @delLinks = $ua1->find_all_links(text => 'Delete'); - # Use the final link to delete the last book - $ua1->get_ok($delLinks[$#delLinks]->url, 'Delete last book'); - # Check that delete worked - $ua1->content_contains("Book List", "Book List page test"); - $ua1->content_contains("Book deleted", "Book was deleted"); - - # User 'test02' should not be able to add a book - $ua2->get_ok("http://localhost/books/url_create/TestTitle2/2/5", "'test02' add"); - $ua2->content_contains("Unauthorized!", "Check 'test02' cannot add"); - -The C test cases uses copious comments to explain each step -of the process. In addition to the techniques shown here, there are a -variety of other methods available in -L (for -example, regex-based matching). Consult the documentation for more -detail. - -B: For I vs. the "full application tests" approach used -by L, see -L. - -B The test script does not test the C and -C actions. That is left as an exercise for the reader -(you should be able to complete that logic using the existing code as a -template). - -To run the new test script, use a command such as: - - $ CATALYST_DEBUG=0 prove --lib lib -v t/live_app01.t - -or - - $ DBIC_TRACE=0 CATALYST_DEBUG=0 prove --lib lib -v t/live_app01.t - -Experiment with the C, C -and C<-v> settings. If you find that there are errors, use the -techniques discussed in the "Catalyst Debugging" section (Part 6) to -isolate and fix any problems. - -If you want to run the test case under the Perl interactive debugger, -try a command such as: - - $ DBIC_TRACE=0 CATALYST_DEBUG=0 perl -d -Ilib t/live_app01.t - -Note that although this tutorial uses a single custom test case for -simplicity, you may wish to break your tests into different files for -better organization. - -B If you have a test case that fails, you will receive an error -similar to the following: - - # Failed test 'Check we are NOT logged in' - # in t/live_app01.t at line 31. - # searched: "\x{0a}content; - -This will cause the full HTML returned by the request to be displayed. - - -=head1 SUPPORTING BOTH PRODUCTION AND TEST DATABASES - -You may wish to leverage the techniques discussed in this tutorial to -maintain both a "production database" for your live application and a -"testing database" for your test cases. One advantage to -L is that -it runs your full application; however, this can complicate things when -you want to support multiple databases. One solution is to allow the -database specification to be overridden with an environment variable. -For example, open C in your editor and -change the C<__PACKAGE__-Econfig(...> declaration to resemble: - - my $dsn = $ENV{MYAPP_DSN} ||= 'dbi:SQLite:myapp.db'; - __PACKAGE__->config( - schema_class => 'MyAppDB', - connect_info => [ - $dsn, - '', - '', - { AutoCommit => 1 }, - - ], - ); - -Then, when you run your test case, you can use commands such as: - - $ cp myapp.db myappTEST.db - $ CATALYST_DEBUG=0 MYAPP_DSN="dbi:SQLite:myappTEST.db" prove --lib lib -v t/live_app01.t - -This will modify the DSN only while the test case is running. If you -launch your normal application without the C environment -variable defined, it will default to the same C as -before. - - -=head1 AUTHOR - -Kennedy Clark, C - -Please report any errors, issues or suggestions to the author. The -most recent version of the Catalyst Tutorial can be found at -L. - -Copyright 2006, Kennedy Clark, under Creative Commons License -(L). -