[Checkins] SVN: zope3book/trunk/ - Use ticketcollector as an exmample for Testing chapter
Baiju M
baiju.m.mail at gmail.com
Sat Feb 28 00:09:13 EST 2009
Log message for revision 97362:
- Use ticketcollector as an exmample for Testing chapter
- Expand Testing chapter
Changed:
A zope3book/trunk/code/06_testing/
A zope3book/trunk/code/06_testing/stage1/
A zope3book/trunk/code/06_testing/stage1/example1/
A zope3book/trunk/code/06_testing/stage1/example1/example1.py
A zope3book/trunk/code/06_testing/stage1/example1/example1.txt
A zope3book/trunk/code/06_testing/stage1/example1/test_example1.py
A zope3book/trunk/code/06_testing/stage2/
A zope3book/trunk/code/06_testing/stage2/example1/
A zope3book/trunk/code/06_testing/stage2/example1/example1.py
A zope3book/trunk/code/06_testing/stage2/example1/example1.txt
A zope3book/trunk/code/06_testing/stage2/example1/test_example1.py
A zope3book/trunk/code/06_testing/stage3/
A zope3book/trunk/code/06_testing/stage3/ticketcollector/
A zope3book/trunk/code/06_testing/stage3/ticketcollector/bootstrap/
A zope3book/trunk/code/06_testing/stage3/ticketcollector/bootstrap/bootstrap.py
A zope3book/trunk/code/06_testing/stage3/ticketcollector/buildout.cfg
A zope3book/trunk/code/06_testing/stage3/ticketcollector/setup.py
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/README.txt
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/__init__.py
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/application.zcml
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/browser.py
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/ftesting.zcml
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/testing.py
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/__init__.py
A zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/test_collector.py
U zope3book/trunk/source/testing.rst
-=-
Added: zope3book/trunk/code/06_testing/stage1/example1/example1.py
===================================================================
--- zope3book/trunk/code/06_testing/stage1/example1/example1.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage1/example1/example1.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,2 @@
+def goodmorning(name):
+ "This returns a good morning message"
Added: zope3book/trunk/code/06_testing/stage1/example1/example1.txt
===================================================================
--- zope3book/trunk/code/06_testing/stage1/example1/example1.txt (rev 0)
+++ zope3book/trunk/code/06_testing/stage1/example1/example1.txt 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,17 @@
+These are test cases for example1 module.
+
+First import the module::
+
+ >>> import example1
+
+Now call the function `goodmorning` without any arguments::
+
+ >>> example1.goodmorning()
+ Traceback (most recent call last):
+ ...
+ TypeError: goodmorning() takes exactly 1 argument (0 given)
+
+Now call the function goodmorning with one argument::
+
+ >>> example1.goodmorning('Jack')
+ 'Good morning, Jack!'
Added: zope3book/trunk/code/06_testing/stage1/example1/test_example1.py
===================================================================
--- zope3book/trunk/code/06_testing/stage1/example1/test_example1.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage1/example1/test_example1.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,10 @@
+import unittest
+import doctest
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite('example1.txt'),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Added: zope3book/trunk/code/06_testing/stage2/example1/example1.py
===================================================================
--- zope3book/trunk/code/06_testing/stage2/example1/example1.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage2/example1/example1.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,3 @@
+def goodmorning(name):
+ "This returns a good morning message"
+ return "Good morning, %s!" % name
Added: zope3book/trunk/code/06_testing/stage2/example1/example1.txt
===================================================================
--- zope3book/trunk/code/06_testing/stage2/example1/example1.txt (rev 0)
+++ zope3book/trunk/code/06_testing/stage2/example1/example1.txt 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,17 @@
+These are test cases for example1 module.
+
+First import the module::
+
+ >>> import example1
+
+Now call the function `goodmorning` without any arguments::
+
+ >>> example1.goodmorning()
+ Traceback (most recent call last):
+ ...
+ TypeError: goodmorning() takes exactly 1 argument (0 given)
+
+Now call the function goodmorning with one argument::
+
+ >>> example1.goodmorning('Jack')
+ 'Good morning, Jack!'
Added: zope3book/trunk/code/06_testing/stage2/example1/test_example1.py
===================================================================
--- zope3book/trunk/code/06_testing/stage2/example1/test_example1.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage2/example1/test_example1.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,10 @@
+import unittest
+import doctest
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite('example1.txt'),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: zope3book/trunk/code/06_testing/stage3/ticketcollector
___________________________________________________________________
Added: svn:ignore
+ develop-eggs
bin
parts
.installed.cfg
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/bootstrap/bootstrap.py
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/bootstrap/bootstrap.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/bootstrap/bootstrap.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,55 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 75593 2007-05-06 21:11:27Z jim $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+ import pkg_resources
+except ImportError:
+ ez = {}
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/buildout.cfg
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/buildout.cfg (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/buildout.cfg 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,25 @@
+[buildout]
+develop = .
+parts = ticketcollectorapp instance test
+extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+versions = versions
+
+[zope3]
+location =
+
+[ticketcollectorapp]
+recipe = zc.zope3recipes:app
+site.zcml = <include package="ticketcollector" file="application.zcml" />
+eggs = ticketcollector
+
+[instance]
+recipe = zc.zope3recipes:instance
+application = ticketcollectorapp
+zope.conf = ${database:zconfig}
+
+[database]
+recipe = zc.recipe.filestorage
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = ticketcollector [test]
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/setup.py
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/setup.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/setup.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,20 @@
+from setuptools import setup, find_packages
+
+setup(
+ name='ticketcollector',
+ version='0.1',
+
+ packages=find_packages('src'),
+ package_dir={'': 'src'},
+
+ install_requires=['setuptools',
+ 'zope.app.zcmlfiles',
+ 'zope.app.twisted',
+ 'zope.app.securitypolicy',
+ ],
+ extras_require=dict(test=['zope.app.testing',
+ 'zope.testbrowser',
+ ]),
+ include_package_data=True,
+ zip_safe=False,
+ )
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/README.txt
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/README.txt (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/README.txt 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,23 @@
+Create the browser object::
+
+ >>> from zope.testbrowser.testing import Browser
+ >>> browser = Browser()
+
+Provide creditial information::
+
+ >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+ >>> browser.addHeader('Accept-Language', 'en-US')
+
+Open main page::
+
+ >>> browser.open('http://localhost/')
+ >>> browser.url
+ 'http://localhost/'
+
+Open hello page::
+
+ >>> browser.open('http://localhost/@@hello')
+ >>> browser.url
+ 'http://localhost/@@hello'
+ >>> 'Hello World' in browser.contents
+ True
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/__init__.py
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/__init__.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/__init__.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1 @@
+#Python package
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/application.zcml
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/application.zcml (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/application.zcml 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,63 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope"
+ >
+<include package="zope.app.securitypolicy" file="meta.zcml" />
+
+<include package="zope.app.zcmlfiles" />
+<include package="zope.app.authentication" />
+<include package="zope.app.securitypolicy" />
+<include package="zope.app.twisted" />
+
+<securityPolicy
+ component="zope.app.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+<role id="zope.Anonymous" title="Everybody"
+ description="All users have this role implicitly" />
+<role id="zope.Manager" title="Site Manager" />
+<role id="zope.Member" title="Site Member" />
+
+<grant permission="zope.View"
+ role="zope.Anonymous" />
+<grant permission="zope.app.dublincore.view"
+ role="zope.Anonymous" />
+
+<grantAll role="zope.Manager" />
+
+<unauthenticatedPrincipal
+ id="zope.anybody"
+ title="Unauthenticated User" />
+
+<unauthenticatedGroup
+ id="zope.Anybody"
+ title="Unauthenticated Users" />
+
+<authenticatedGroup
+ id="zope.Authenticated"
+ title="Authenticated Users" />
+
+<everybodyGroup
+ id="zope.Everybody"
+ title="All Users" />
+
+<principal
+ id="zope.manager"
+ title="Manager"
+ login="admin"
+ password_manager="Plain Text"
+ password="admin"
+ />
+
+<grant
+ role="zope.Manager"
+ principal="zope.manager" />
+
+<browser:page
+ for="*"
+ name="hello"
+ permission="zope.Public"
+ class="ticketcollector.browser.HelloView"
+/>
+
+</configure>
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/browser.py
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/browser.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/browser.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,15 @@
+from zope.publisher.browser import BrowserView
+
+class HelloView(BrowserView):
+
+ def __call__(self):
+ return """
+ <html>
+ <head>
+ <title>Hello World</title>
+ </head>
+ <body>
+ Hello World
+ </body>
+ </html>
+ """
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/ftesting.zcml
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/ftesting.zcml (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/ftesting.zcml 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,63 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope"
+ >
+<include package="zope.app.securitypolicy" file="meta.zcml" />
+
+<include package="zope.app.zcmlfiles" />
+<include package="zope.app.authentication" />
+<include package="zope.app.securitypolicy" />
+<include package="zope.app.twisted" />
+
+<securityPolicy
+ component="zope.app.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+<role id="zope.Anonymous" title="Everybody"
+ description="All users have this role implicitly" />
+<role id="zope.Manager" title="Site Manager" />
+<role id="zope.Member" title="Site Member" />
+
+<grant permission="zope.View"
+ role="zope.Anonymous" />
+<grant permission="zope.app.dublincore.view"
+ role="zope.Anonymous" />
+
+<grantAll role="zope.Manager" />
+
+<unauthenticatedPrincipal
+ id="zope.anybody"
+ title="Unauthenticated User" />
+
+<unauthenticatedGroup
+ id="zope.Anybody"
+ title="Unauthenticated Users" />
+
+<authenticatedGroup
+ id="zope.Authenticated"
+ title="Authenticated Users" />
+
+<everybodyGroup
+ id="zope.Everybody"
+ title="All Users" />
+
+<principal
+ id="zope.manager"
+ title="Manager"
+ login="admin"
+ password_manager="Plain Text"
+ password="admin"
+ />
+
+<grant
+ role="zope.Manager"
+ principal="zope.manager" />
+
+<browser:page
+ for="*"
+ name="hello"
+ permission="zope.Public"
+ class="ticketcollector.browser.HelloView"
+/>
+
+</configure>
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/testing.py
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/testing.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/testing.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,6 @@
+import os
+from zope.app.testing.functional import ZCMLLayer
+
+TicketCollectorLayer = ZCMLLayer(
+ os.path.join(os.path.split(__file__)[0], 'ftesting.zcml'),
+ __name__, 'TicketCollectorLayer', allow_teardown=True)
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/__init__.py
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/__init__.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/__init__.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1 @@
+#Python package
Added: zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/test_collector.py
===================================================================
--- zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/test_collector.py (rev 0)
+++ zope3book/trunk/code/06_testing/stage3/ticketcollector/src/ticketcollector/tests/test_collector.py 2009-02-28 05:09:11 UTC (rev 97362)
@@ -0,0 +1,10 @@
+from zope.app.testing.functional import FunctionalDocFileSuite
+from ticketcollector.testing import TicketCollectorLayer
+import unittest
+
+def test_suite():
+ ticketcollector = FunctionalDocFileSuite("../README.txt")
+ ticketcollector.layer = TicketCollectorLayer
+ return unittest.TestSuite((
+ ticketcollector,
+ ))
Modified: zope3book/trunk/source/testing.rst
===================================================================
--- zope3book/trunk/source/testing.rst 2009-02-28 00:53:24 UTC (rev 97361)
+++ zope3book/trunk/source/testing.rst 2009-02-28 05:09:11 UTC (rev 97362)
@@ -5,10 +5,11 @@
Introduction
------------
-As you know by now, Zope 3 gains its incredible stability from
-testing any code in great detail. The currently most common method
-is to write unit tests. This chapter introduces unit tests - which
-are Zope 3 independent - and introduces some of the subtleties.
+Zope 3 gained its incredible stability from testing any code in great
+detail. Zope 3 packages has almost 100% test coverage. Zope 3
+developers write unit tests, and integration tests wherever required.
+This chapter introduces unit tests and integration tests and some of
+the subtleties.
Unit testing
@@ -17,24 +18,26 @@
.. index::
single: unit testing; testing
-Unit test can be written using `unittest`, `zope.unittest`, `nose`,
-`py.test` etc. Another approach to write unit test is using doctest.
-Doctest-based unit tests are the most used way to write unit tests in
-Zope 3. During the development and maintenance of Zope 3 packages
-developers use test driven development (TDD) style process.
+You can write unit tests using Python's built-in module called,
+`unittest` or other third party modules like `zope.testing`, `nose`
+and `py.test`. There is another approach called, doctest which use
+plain text files to write unit tests. Doctests are the most widely
+technique to write unit tests in Zope 3. During the development and
+maintenance of Zope 3 packages, developers use test driven
+development (TDD) style process.
To explain the idea of unit testing, consider a use case. A module
-is required with a function which returns "Good morning, name!". The
-name will be given as an argument. Before writing the real code
-write the unit test for this. In fact, you will be writing the real
-code and it's test cases almost in parallel. So, create a file named
+is required with a function which accepts one argument (`name`) and
+return: "Good morning, name!". Before writing the real code, write
+the unit test for this. In fact, you will be writing the real code
+and its test cases almost in parallel. So, create a file named
`example1.py` with the following function definition::
def goodmorning(name):
"This returns a good morning message"
-See, you have not yet written the logic. But this is necessary to
-run tests successfully with failures!. Ok, now create a file named
+Here, you have not yet written the logic. But this is necessary to
+run tests, initially with failures. Now, create a file named
`example1.txt` with test cases. You can use reStructuredText
format::
@@ -56,9 +59,9 @@
>>> example1.goodmorning('Jack')
'Good morning, Jack!'
-See, the examples are written like executed from prompt. You can use
-your python prompt and copy paste from there. Now create another
-file names `test_example1.py` with this content::
+Here, the examples are written like executed from prompt. You can
+use your python prompt and copy paste from there. Finally, create
+another file names `test_example1.py` with this content::
import unittest
import doctest
@@ -71,9 +74,9 @@
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
-This is just boilerplate code for running the test. Now run the test
-using python2.4 test_example1.py command. You will get output with
-following text::
+This is just a boilerplate code for running the tests. Now, run the
+test using ``python2.5 test_example1.py`` command. You will get
+output with following text::
File "example1.txt", line 16, in example1.txt
Failed example:
@@ -82,17 +85,17 @@
'Good morning, Jack!'
Got nothing
-Now, one test failed, so, implement the function now::
+As you can see, one test is failed. So, implement the function now::
def goodmorning(name):
"This returns a good morning message"
return "Good morning, %s!" % name
-Run the test again, it should run without failures.
+Run the test again, it should run without any failures.
Now start thinking about other functionalities required for the
-module. Before start coding write about it in text file. Decide
-API, write test, write code, than continue this cycle until you
+module. Before start coding, write about it in text file. Decide
+API, write test, write code, then continue this cycle until you
finish your requirements.
@@ -102,10 +105,10 @@
.. index::
single: running tests; testing
-The Buildout recipe named `zc.recipe.testrunner` would be convenient
-for running test cases. It will create a script to run the test
-cases. For a typical project you can add `test` part in
-configuration like this::
+In Zope 3, you can use the Buildout recipe named
+`zc.recipe.testrunner` for running test cases. It will create a
+script to run the test cases. For a typical project, you can add
+`test` part in configuration like this::
[buildout]
parts = test
@@ -117,10 +120,10 @@
.. index::
single: test runner; testing
-Here the package names is assumed as `ticketcollector` (this is the
+Here, the package names is assumed as `ticketcollector` (this is the
name you given in `setup.py`). Also here I assume that there is an
-`extras_require` argument for `setup` function in `setup.py`.
-The argument can be given something like this::
+`extras_require` argument for `setup` function in `setup.py`. The
+argument can be given something like this::
extras_require=dict(test=['zope.app.testing',
'zope.testbrowser',
@@ -135,9 +138,68 @@
the unit tests, change to instance home::
$ cd ticketcollector
+ $ ./bin/buildout
$ ./bin/test
+Integration testing
+-------------------
+
+A doctest based testing module named, ``zope.testbrowser`` is used
+for integration/functional testing in Zope 3. Zope use the term
+"functional" more frequently than "integration". Unlike unit tests,
+functional tests are user interface (view) oriented.
+
+The central part of this package is a browser object. First you have
+to create the browser object, to do so, import ``Browser`` class from
+``zope.testbrowser.testing``::
+
+ >>> from zope.testbrowser.testing import Browser
+ >>> browser = Browser()
+
+To open a page::
+
+ >>> browser.open('http://localhost/zopetest/simple.html')
+ >>> browser.url
+ 'http://localhost/zopetest/simple.html'
+
+The ``zope.testbrowser.browser`` module exposes a ``Browser`` class that
+simulates a web browser similar to Mozilla Firefox or IE.
+
+ >>> from zope.testbrowser.browser import Browser
+ >>> browser = Browser()
+
+This version of the browser object can be used to access any web site just as
+you would do using a normal web browser.
+
+There is also a special version of the ``Browser`` class used to do
+functional testing of Zope 3 applications, it can be imported from
+``zope.testbrowser.testing``:
+
+ >>> from zope.testbrowser.testing import Browser
+ >>> browser = Browser()
+
+An initial page to load can be passed to the ``Browser`` constructor:
+
+ >>> browser = Browser('http://localhost/@@/testbrowser/simple.html')
+ >>> browser.url
+ 'http://localhost/@@/testbrowser/simple.html'
+
+The browser can send arbitrary headers; this is helpful for setting the
+"Authorization" header or a language value, so that your tests format values
+the way you expect in your tests, if you rely on zope.i18n locale-based
+formatting or a similar approach.
+
+ >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+ >>> browser.addHeader('Accept-Language', 'en-US')
+
+An existing browser instance can also `open` web pages:
+
+ >>> browser.open('http://localhost/@@/testbrowser/simple.html')
+ >>> browser.url
+ 'http://localhost/@@/testbrowser/simple.html'
+
+
Summary
-------
More information about the Checkins
mailing list