[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