Not logged in - Log In / Register

This page offers some details about writing integration tests for web/browser pages.


Now that we've upgraded to Zope 3.2 we can use zope.testbrowser to do page testing, instead of the traditional way using http() calls. testbrowser page tests are easier to write and understand, since you get easy access to links and form controls in the page. So, for example, you can check whether a link is present, and click on that link to go to some other page. zope.testbrowser can be tricky to use sometimes, though, since you can get weird errors.

In the pagetests there is already a 'browser' object set up ready to use. It has browser.handleErrors = False, to give you a traceback instead of a simple 500 error message if something goes wrong. It will also give a traceback for 404 pages and pages you don't have permission to view.

How to write testbrowser tests

Read lib/zope/testbrowser/README.txt or the online version, to find out everything you can do with the testbrowser.

Read lib/canonical/launchpad/testing/ to find out how you can use page testing helpers.

Read lib/canonical/launchpad/pagetests/README.txt to find out how to run page tests and the available configured users. These are the highlights.

You can find many pagetest helpers in lib/canonical/launchpad/testing/, so before starting to write any pagetest check that file out.

Using multiple browsers

If you test multiple HTTP situations -- such as logging in as different people -- in the same file, you need to use different Browser() objects. There are three available automatically:

To create another one:

from zope.testbrowser.testing import Browser
my_browser = Browser()

Or to test as a particular logged-in person:

my_browser = setupBrowser(auth='Basic')

Testing the contents of the page

Viewing a page as seen by the testbrowser

When writing or debugging a page test, you may wonder, "What does the page really look like in a browser at this point?" You could walk through the entire test manually, but there is an easier way.

First, edit your config/default/launchpad.conf file and change the dbname in your <canonical default> section to be 'launchpad_ftest'.

Next, stick a pdb break point at the place in your page test that you want to examine:

     >>> import pdb; pdb.set_trace() 

Now run the page test as you normally would using bin/test. When you hit the break point, go to a different shell and do 'make run'. Because of your dbname change, this will run the site against the testing database, so all the state your page test has built up will be available to you. Now poke around in your browser all you want.

Once your page test ends (maybe because you've killed it), your browser session will be unhappy because the launchpad_ftest database is torn down when bin/test exits. Make sure you revert your launchpad.conf changes before you commit. (BarryWarsaw plans on making this easier when lazr config lands.)

Dealing with old-style page tests

There's no reason to rewrite existing page tests, but if some test starts to fail, it's often easier to rewrite it using zope.testbrowser than to fix the existing one. For example, if you have a page test that submits a form, and the test is to change a single field in the form, the test might start failing if some required field (with a default value) gets added to the form. The traditional pagetest would fail since the required field is missing. Rewriting it using zope.testbrowser would look something like this:
browser.getControl('Some Field').value = 'foo'

That is, it doesn't have to care about the other field values, they will have the default values.

Organizing tests into stories

Prefer standalone tests and short stories rather than long stories. source

Unresolved issues

There's currently no equivalence to in RF for creating zope.testbrowser tests, but there is another package, zope.testrecorder, which we could pull in.


PageTests (last edited 2010-04-27 02:48:01 by adiroiban)