[Checkins] SVN: zope.testbrowser/branches/benji-reduce-testing-dependencies/ rework zope.testbrowser testing; will eventually allow the different flavors of

Benji York benji at zope.com
Mon Sep 17 06:34:53 EDT 2007


Log message for revision 79707:
  rework zope.testbrowser testing; will eventually allow the different flavors of
  testbrowser to all run the same tests; also helps with the required packages
  trimming
  

Changed:
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/README.txt
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/buildout.cfg
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/setup.py
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/README.txt
  A   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/Zope.txt
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/browser.py
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/forms.html
  A   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/index.html
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/navigate.html
  D   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/simple.html
  A   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/target.html
  A   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/headers.txt
  U   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/tests.py
  A   zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/zopetests.py

-=-
Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/README.txt
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/README.txt	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/README.txt	2007-09-17 10:34:53 UTC (rev 79707)
@@ -1,11 +1,17 @@
 Overview
 ========
 
-``zope.testbrowser`` provides an easy-to-use programmable web browser
-with special focus on testing.  It is used in Zope, but it's not Zope
-specific at all.  For instance, it can be used to test or otherwise
-interact with any web site.
+The zope.testbrowser package provides web user agents (browsers) with
+programmatic interfaces designed to be used for testing web applications,
+especially in conjunction with doctests.  This project originates in the Zope 3
+community, but is not Zope-specific.
 
+There are currently three type of testbrowser provided.  One for accessing web
+sites via HTTP (zope.testbrowser.browser), one for directly accessing a Zope 3
+application (zope.testbrowser.testing), and one that controls a Firefox web
+browser (zope.testbrowser.real).
+
+
 Changes
 =======
 

Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/buildout.cfg
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/buildout.cfg	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/buildout.cfg	2007-09-17 10:34:53 UTC (rev 79707)
@@ -1,29 +1,34 @@
 [buildout]
 develop = .
-parts = test
+parts = test-zope test-no-zope
 versions = versions
 find-links = http://download.zope.org/distribution/
 
-[test]
+[test-zope]
 recipe = zc.recipe.testrunner
-defaults = ['--tests-pattern', '^f?tests$']
+defaults = ['--tests-pattern', '^zopetests$', '-1', '--auto-color']
 eggs = zope.testbrowser [zope]
 
+[test-no-zope]
+recipe = zc.recipe.testrunner
+defaults = ['-1', '--auto-color']
+eggs = zope.testbrowser
+
 [versions]
 ClientForm = 0.2.7
 RestrictedPython = 3.4.2
-ZConfig = 2.4a6
+ZConfig = 2.5
 ZODB3 = 3.9.0-dev-r77011
 docutils = 0.4
 mechanize = 0.1.7b
 pytz = 2007f
-setuptools = 0.6c6
+setuptools = 0.6c7
 zc.buildout = 1.0.0b30
 zc.recipe.egg = 1.0.0b6
 zc.recipe.testrunner = 1.0.0b8
 zdaemon = 2.0.0
 zodbcode = 3.4.0b1dev-r75670
-zope.annotation = 3.4.0b1.dev-r75758
+zope.annotation = 3.4.0
 zope.app.applicationcontrol = 3.4-dev-r73715
 zope.app.appsetup = 3.4.0a1
 zope.app.authentication = 3.4.0b1
@@ -54,14 +59,14 @@
 zope.app.securitypolicy = 3.4.0a1
 zope.app.session = 3.5.0dev-r77333
 zope.app.testing = 3.4.0b1-r78707
-zope.app.wsgi = 3.4.0b1dev-r75415
+zope.app.wsgi = 3.4.0
 zope.app.zapi = 3.4.0a1
 zope.app.zcmlfiles = 3.4.0a1
 zope.app.zopeappgenerations = 3.4.0a1
-zope.cachedescriptors = 3.4.0b1-r75830
+zope.cachedescriptors = 3.4.0
 zope.component = 3.4.0a1
 zope.configuration = 3.4.0b1
-zope.contenttype = 3.4.0a1
+zope.contenttype = 3.4.0
 zope.copypastemove = 3.4.0a1
 zope.datetime = 3.4.0
 zope.deferredimport = 3.4.0
@@ -76,9 +81,9 @@
 zope.i18n = 3.4.0b5.dev-r78840
 zope.i18nmessageid = 3.4.0
 zope.interface = 3.4.0
-zope.lifecycleevent = 3.4.0a1
+zope.lifecycleevent = 3.4.0
 zope.location = 3.4.0b2
-zope.minmax = 1.0b1
+zope.minmax = 1.0b2
 zope.modulealias = 3.4.0a1
 zope.pagetemplate = 3.4.0a1
 zope.proxy = 3.4.0
@@ -86,7 +91,7 @@
 zope.schema = 3.4.0b1dev-r77624
 zope.security = 3.4.0b5
 zope.size = 3.4.0
-zope.structuredtext = 3.4.0a1
+zope.structuredtext = 3.4.0
 zope.tal = 3.4.0b1
 zope.tales = 3.4.0a1
 zope.testing = 3.5.1

Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/setup.py
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/setup.py	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/setup.py	2007-09-17 10:34:53 UTC (rev 79707)
@@ -30,7 +30,8 @@
     version = '3.4.2dev',
     url = 'http://pypi.python.org/pypi/zope.testbrowser',
     license = 'ZPL 2.1',
-    description = 'Programmable browser for functional black-box tests',
+    description = 'Programmable browser for functional black-box tests'
+        ' (not Zope-specific)',
     author = 'Zope Corporation and Contributors',
     author_email = 'zope3-dev at zope.org',
     long_description = long_description,

Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/README.txt
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/README.txt	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/README.txt	2007-09-17 10:34:53 UTC (rev 79707)
@@ -1,42 +1,17 @@
 Detailed Documentation
 ======================
 
-The ``zope.testbrowser.browser`` module exposes a ``Browser`` class that
-simulates a web browser similar to Mozilla Firefox or IE.
+Before being of much interest, we need to open a web page.  ``Browser``
+instances have a ``base`` attribute that sets the URL from which ``open``ed
+URLs are relative.  This lets you target tests at servers running in various,
+or even variable locations (like using randomly chosen ports).
 
-    >>> 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.base = 'http://localhost:%s/' % TEST_PORT
+    >>> browser.open('index.html')
     >>> browser.url
-    'http://localhost/@@/testbrowser/simple.html'
+    'http://localhost:.../index.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'
-
 Once you have opened a web page initially, best practice for writing
 testbrowser doctests suggests using 'click' to navigate further (as discussed
 below), except in unusual circumstances.
@@ -44,9 +19,9 @@
 The test browser complies with the IBrowser interface; see
 ``zope.testbrowser.interfaces`` for full details on the interface.
 
-    >>> from zope.testbrowser import interfaces
+    >>> import zope.testbrowser.interfaces
     >>> from zope.interface.verify import verifyObject
-    >>> verifyObject(interfaces.IBrowser, browser)
+    >>> verifyObject(zope.testbrowser.interfaces.IBrowser, browser)
     True
 
 
@@ -85,90 +60,61 @@
 
 Not all URLs return HTML.  Of course our simple page does:
 
-    >>> browser.open('http://localhost/@@/testbrowser/simple.html')
     >>> browser.isHtml
     True
 
 But if we load an image (or other binary file), we do not get HTML:
 
-    >>> browser.open('http://localhost/@@/testbrowser/zope3logo.gif')
+    >>> browser.open('zope3logo.gif')
     >>> browser.isHtml
     False
 
 
-
 HTML Page Title
 ----------------
 
 Another useful helper property is the title:
 
-    >>> browser.open('http://localhost/@@/testbrowser/simple.html')
+    >>> browser.open('index.html')
     >>> browser.title
     'Simple Page'
 
 If a page does not provide a title, it is simply ``None``:
 
-    >>> browser.open('http://localhost/@@/testbrowser/notitle.html')
+    >>> browser.open('notitle.html')
     >>> browser.title
 
 However, if the output is not HTML, then an error will occur trying to access
 the title:
 
-    >>> browser.open('http://localhost/@@/testbrowser/zope3logo.gif')
+    >>> browser.open('zope3logo.gif')
     >>> browser.title
     Traceback (most recent call last):
     ...
     BrowserStateError: not viewing HTML
 
 
-Headers
--------
-
-As you can see, the `contents` of the browser does not return any HTTP
-headers.  The headers are accessible via a separate attribute, which is an
-``httplib.HTTPMessage`` instance (httplib is a part of Python's standard
-library):
-
-    >>> browser.open('http://localhost/@@/testbrowser/simple.html')
-    >>> browser.headers
-    <httplib.HTTPMessage instance...>
-
-The headers can be accessed as a string:
-
-    >>> print browser.headers
-    Status: 200 OK
-    Content-Length: 123
-    Content-Type: text/html;charset=utf-8
-    X-Powered-By: Zope (www.zope.org), Python (www.python.org)
-
-Or as a mapping:
-
-    >>> browser.headers['content-type']
-    'text/html;charset=utf-8'
-
-
 Navigation and Link Objects
 ---------------------------
 
-If you want to simulate clicking on a link, get the link and `click` on it.
-In the `navigate.html` file there are several links set up to demonstrate the
-capabilities of the link objects and their `click` method.
+If you want to simulate clicking on a link, get the link and call its `click`
+method.  In the `navigate.html` file there are several links set up to
+demonstrate the capabilities of the link objects and their `click` method.
 
 The simplest way to get a link is via the anchor text.  In other words
 the text you would see in a browser (text and url searches are substring
 searches):
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
+    >>> browser.open('navigate.html')
     >>> browser.contents
-    '...<a href="navigate.html?message=By+Link+Text">Link Text</a>...'
+    '...<a href="target.html">Link Text</a>...'
     >>> link = browser.getLink('Link Text')
     >>> link
-    <Link text='Link Text'
-      url='http://localhost/@@/testbrowser/navigate.html?message=By+Link+Text'>
+    <Link text='Link Text' url='http://localhost:.../target.html'>
 
 Link objects comply with the ILink interface.
 
-    >>> verifyObject(interfaces.ILink, link)
+    >>> verifyObject(zope.testbrowser.interfaces.ILink, link)
     True
 
 Links expose several attributes for easy access.
@@ -177,22 +123,22 @@
     'Link Text'
     >>> link.tag # links can also be image maps.
     'a'
-    >>> link.url # it's normalized
-    'http://localhost/@@/testbrowser/navigate.html?message=By+Link+Text'
+    >>> link.url # normalized to an absolute URL
+    'http://localhost:.../target.html'
     >>> link.attrs
-    {'href': 'navigate.html?message=By+Link+Text'}
+    {'href': 'target.html'}
 
 Links can be "clicked" and the browser will navigate to the referenced URL.
 
     >>> link.click()
     >>> browser.url
-    'http://localhost/@@/testbrowser/navigate.html?message=By+Link+Text'
+    'http://localhost:.../target.html'
     >>> browser.contents
-    '...Message: <em>By Link Text</em>...'
+    '...This page is the target of a link...'
 
 When finding a link by its text, whitespace is normalized.
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
+    >>> browser.open('navigate.html')
     >>> browser.contents
     '...> Link Text \n    with     Whitespace\tNormalization (and parens) </...'
     >>> link = browser.getLink('Link Text with Whitespace Normalization '
@@ -203,14 +149,13 @@
     'Link Text with Whitespace Normalization (and parens)'
     >>> link.click()
     >>> browser.url
-    'http://localhost/@@/testbrowser/navigate.html?message=By+Link+Text+with+Normalization'
-    >>> browser.contents
-    '...Message: <em>By Link Text with Normalization</em>...'
+    'http://localhost:.../target.html'
 
 When a link text matches more than one link, by default the first one is
 chosen. You can, however, specify the index of the link and thus retrieve a
 later matching link:
 
+    >>> browser.open('navigate.html')
     >>> browser.getLink('Link Text')
     <Link text='Link Text' ...>
 
@@ -225,48 +170,38 @@
     ...
     ExpiredError
 
-You can also find the link by its URL,
+You can also find links by URL,
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
-    >>> browser.contents
-    '...<a href="navigate.html?message=By+URL">Using the URL</a>...'
-
-    >>> browser.getLink(url='?message=By+URL').click()
+    >>> browser.open('navigate.html')
+    >>> browser.getLink(url='target.html').click()
     >>> browser.url
-    'http://localhost/@@/testbrowser/navigate.html?message=By+URL'
-    >>> browser.contents
-    '...Message: <em>By URL</em>...'
+    'http://localhost:.../target.html'
 
 or its id:
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
+    >>> browser.open('navigate.html')
     >>> browser.contents
-    '...<a href="navigate.html?message=By+Id"
-    id="anchorid">By Anchor Id</a>...'
+    '...<a href="target.html" id="anchorid">By Anchor Id</a>...'
 
     >>> browser.getLink(id='anchorid').click()
     >>> browser.url
-    'http://localhost/@@/testbrowser/navigate.html?message=By+Id'
-    >>> browser.contents
-    '...Message: <em>By Id</em>...'
+    'http://localhost:.../target.html'
 
 You thought we were done here? Not so quickly.  The `getLink` method also
 supports image maps, though not by specifying the coordinates, but using the
 area's id:
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
+    >>> browser.open('navigate.html')
     >>> link = browser.getLink(id='zope3')
     >>> link.tag
     'area'
     >>> link.click()
     >>> browser.url
-    'http://localhost/@@/testbrowser/navigate.html?message=Zope+3+Name'
-    >>> browser.contents
-    '...Message: <em>Zope 3 Name</em>...'
+    'http://localhost:.../target.html'
 
 Getting a nonexistent link raises an exception.
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
+    >>> browser.open('navigate.html')
     >>> browser.getLink('This does not exist')
     Traceback (most recent call last):
     ...
@@ -278,21 +213,21 @@
 
 Like in any normal browser, you can reload a page:
 
-    >>> browser.open('http://localhost/@@/testbrowser/simple.html')
+    >>> browser.open('index.html')
     >>> browser.url
-    'http://localhost/@@/testbrowser/simple.html'
+    'http://localhost:.../index.html'
     >>> browser.reload()
     >>> browser.url
-    'http://localhost/@@/testbrowser/simple.html'
+    'http://localhost:.../index.html'
 
 You can also go back:
 
-    >>> browser.open('http://localhost/@@/testbrowser/notitle.html')
+    >>> browser.open('notitle.html')
     >>> browser.url
-    'http://localhost/@@/testbrowser/notitle.html'
+    'http://localhost:.../notitle.html'
     >>> browser.goBack()
     >>> browser.url
-    'http://localhost/@@/testbrowser/simple.html'
+    'http://localhost:.../index.html'
 
 
 Controls
@@ -302,7 +237,7 @@
 and fill in values for the controls of input forms.  To do so, let's first open
 a page that has a bunch of controls:
 
-    >>> browser.open('http://localhost/@@/testbrowser/controls.html')
+    >>> browser.open('controls.html')
 
 Obtaining a Control
 ~~~~~~~~~~~~~~~~~~~
@@ -449,7 +384,7 @@
     >>> ctrl = browser.getControl('Text Control')
     >>> ctrl
     <Control name='text-value' type='text'>
-    >>> verifyObject(interfaces.IControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IControl, ctrl)
     True
 
 They have several useful attributes:
@@ -492,7 +427,7 @@
     False
     >>> ctrl.multiple
     True
-    >>> verifyObject(interfaces.IListControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IListControl, ctrl)
     True
 
   - 'options' lists all available value options.
@@ -562,7 +497,8 @@
     '2'
     >>> browser.getControl('Zwei').selected
     True
-    >>> verifyObject(interfaces.IItemControl, browser.getControl('Zwei'))
+    >>> verifyObject(zope.testbrowser.interfaces.IItemControl,
+    ...     browser.getControl('Zwei'))
     True
     >>> browser.getControl('Ein').selected = True
     >>> browser.getControl('Ein').selected
@@ -594,7 +530,7 @@
     >>> ctrl = browser.getControl('Password Control')
     >>> ctrl
     <Control name='password-value' type='password'>
-    >>> verifyObject(interfaces.IControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IControl, ctrl)
     True
     >>> ctrl.value
     'Password'
@@ -611,7 +547,7 @@
     >>> ctrl = browser.getControl(name='hidden-value')
     >>> ctrl
     <Control name='hidden-value' type='hidden'>
-    >>> verifyObject(interfaces.IControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IControl, ctrl)
     True
     >>> ctrl.value
     'Hidden'
@@ -626,7 +562,7 @@
     >>> ctrl = browser.getControl('Text Area Control')
     >>> ctrl
     <Control name='textarea-value' type='textarea'>
-    >>> verifyObject(interfaces.IControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IControl, ctrl)
     True
     >>> ctrl.value
     '        Text inside\n        area!\n      '
@@ -650,7 +586,7 @@
     >>> ctrl = browser.getControl('File Control')
     >>> ctrl
     <Control name='file-value' type='file'>
-    >>> verifyObject(interfaces.IControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IControl, ctrl)
     True
     >>> ctrl.value is None
     True
@@ -672,7 +608,7 @@
     >>> ctrl = browser.getControl('Single Select Control')
     >>> ctrl
     <ListControl name='single-select-value' type='select'>
-    >>> verifyObject(interfaces.IListControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IListControl, ctrl)
     True
     >>> ctrl.value
     ['1']
@@ -708,7 +644,7 @@
     >>> ctrl = browser.getControl(name='single-unvalued-checkbox-value')
     >>> ctrl
     <ListControl name='single-unvalued-checkbox-value' type='checkbox'>
-    >>> verifyObject(interfaces.IListControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IListControl, ctrl)
     True
     >>> ctrl.value
     True
@@ -724,7 +660,7 @@
     >>> ctrl.displayValue
     []
     >>> verifyObject(
-    ...     interfaces.IItemControl,
+    ...     zope.testbrowser.interfaces.IItemControl,
     ...     browser.getControl('Single Unvalued Checkbox'))
     True
     >>> browser.getControl('Single Unvalued Checkbox').optionValue
@@ -750,7 +686,7 @@
     >>> ctrl = browser.getControl(name='single-valued-checkbox-value')
     >>> ctrl
     <ListControl name='single-valued-checkbox-value' type='checkbox'>
-    >>> verifyObject(interfaces.IListControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IListControl, ctrl)
     True
     >>> ctrl.value
     ['1']
@@ -766,7 +702,7 @@
     >>> ctrl.displayValue
     []
     >>> verifyObject(
-    ...     interfaces.IItemControl,
+    ...     zope.testbrowser.interfaces.IItemControl,
     ...     browser.getControl('Single Valued Checkbox'))
     True
     >>> browser.getControl('Single Valued Checkbox').selected
@@ -789,7 +725,7 @@
     >>> ctrl = browser.getControl(name='multi-checkbox-value')
     >>> ctrl
     <ListControl name='multi-checkbox-value' type='checkbox'>
-    >>> verifyObject(interfaces.IListControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IListControl, ctrl)
     True
     >>> ctrl.value
     ['1', '3']
@@ -811,7 +747,8 @@
     '2'
     >>> browser.getControl('Two').selected
     True
-    >>> verifyObject(interfaces.IItemControl, browser.getControl('Two'))
+    >>> verifyObject(zope.testbrowser.interfaces.IItemControl,
+    ...     browser.getControl('Two'))
     True
     >>> browser.getControl('Three').selected = True
     >>> browser.getControl('Three').selected
@@ -861,7 +798,7 @@
 
     >>> ctrl
     <ListControl name='radio-value' type='radio'>
-    >>> verifyObject(interfaces.IListControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IListControl, ctrl)
     True
     >>> ctrl.disabled
     False
@@ -884,7 +821,7 @@
     >>> ctrl = browser.getControl(name='image-value')
     >>> ctrl
     <ImageControl name='image-value' type='image'>
-    >>> verifyObject(interfaces.IImageSubmitControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.IImageSubmitControl, ctrl)
     True
     >>> ctrl.value
     ''
@@ -904,7 +841,7 @@
     <SubmitControl name='submit-value' type='submit'>
     >>> browser.getControl('Submit') # multiple labels, but same control
     <SubmitControl name='submit-value' type='submit'>
-    >>> verifyObject(interfaces.ISubmitControl, ctrl)
+    >>> verifyObject(zope.testbrowser.interfaces.ISubmitControl, ctrl)
     True
     >>> ctrl.value
     'Submit This'
@@ -920,21 +857,13 @@
 
     >>> browser.getControl('Text Control').value = 'Other Text'
     >>> browser.getControl('Submit').click()
-    >>> print browser.contents
-    <html>
-    ...
-    <em>Other Text</em>
-    <input type="text" name="text-value" id="text-value" value="Some Text" />
-    ...
-    <em>Submit This</em>
-    <input type="submit" name="submit-value" id="submit-value" value="Submit This" />
-    ...
-    </html>
+    >>> browser.contents
+    "...'text-value': ['Other Text']..."
 
 Note that if you click a submit object after the associated page has expired,
 you will get an error.
 
-    >>> browser.open('http://localhost/@@/testbrowser/controls.html')
+    >>> browser.open('controls.html')
     >>> ctrl = browser.getControl('Submit')
     >>> ctrl.click()
     >>> ctrl.click()
@@ -944,23 +873,13 @@
 
 All the above also holds true for the image control:
 
-    >>> browser.open('http://localhost/@@/testbrowser/controls.html')
+    >>> browser.open('controls.html')
     >>> browser.getControl('Text Control').value = 'Other Text'
     >>> browser.getControl(name='image-value').click()
-    >>> print browser.contents
-    <html>
-    ...
-    <em>Other Text</em>
-    <input type="text" name="text-value" id="text-value" value="Some Text" />
-    ...
-    <em>1</em>
-    <em>1</em>
-    <input type="image" name="image-value" id="image-value"
-           src="zope3logo.gif" />
-    ...
-    </html>
+    >>> browser.contents
+    "...'text-value': ['Other Text']..."
 
-    >>> browser.open('http://localhost/@@/testbrowser/controls.html')
+    >>> browser.open('controls.html')
     >>> ctrl = browser.getControl(name='image-value')
     >>> ctrl.click()
     >>> ctrl.click()
@@ -970,19 +889,11 @@
 
 But when sending an image, you can also specify the coordinate you clicked:
 
-    >>> browser.open('http://localhost/@@/testbrowser/controls.html')
+    >>> browser.open('controls.html')
     >>> browser.getControl(name='image-value').click((50,25))
-    >>> print browser.contents
-    <html>
-    ...
-    <em>50</em>
-    <em>25</em>
-    <input type="image" name="image-value" id="image-value"
-           src="zope3logo.gif" />
-    ...
-    </html>
+    >>> browser.contents
+    "...'image-value.x': ['50']...'image-value.y': ['25']..."
 
-
 Forms
 -----
 
@@ -991,12 +902,12 @@
 be used to do so.  The key value is the form's name or id.  If more than one
 form has the same name or id, the first one will be returned.
 
-    >>> browser.open('http://localhost/@@/testbrowser/forms.html')
+    >>> browser.open('forms.html')
     >>> form = browser.getForm(name='one')
 
 Form instances conform to the IForm interface.
 
-    >>> verifyObject(interfaces.IForm, form)
+    >>> verifyObject(zope.testbrowser.interfaces.IForm, form)
     True
 
 The form exposes several attributes related to forms:
@@ -1014,7 +925,7 @@
   - The action (target URL) when the form is submitted:
 
     >>> form.action
-    'http://localhost/@@/testbrowser/forms.html'
+    'http://localhost:.../forms.html'
 
   - The method (HTTP verb) used to transmit the form data:
 
@@ -1024,7 +935,7 @@
   - The encoding type of the form data:
 
     >>> form.enctype
-    'multipart/form-data'
+    'application/x-www-form-urlencoded'
 
 Besides those attributes, you have also a couple of methods.  Like for the
 browser, you can get control objects, but limited to the current form...
@@ -1035,12 +946,8 @@
 ...and submit the form.
 
     >>> form.submit('Submit')
-    >>> print browser.contents
-    <html>
-    ...
-    <em>First Text</em>
-    ...
-    </html>
+    >>> browser.contents
+    "...'text-value': ['First Text']..."
 
 Submitting also works without specifying a control, as shown below, which is
 it's primary reason for existing in competition with the control submission
@@ -1050,6 +957,7 @@
 the `forms.html` template, we have four forms all having a text control named
 `text-value`.  Now, if I use the browser's `get` method,
 
+    >>> browser.open('forms.html')
     >>> browser.getControl(name='text-value')
     Traceback (most recent call last):
     ...
@@ -1068,11 +976,13 @@
     'Second Text'
     >>> form.submit('Submit')
     >>> browser.contents
-    '...<em>Second Text</em>...'
+    "...'text-value': ['Second Text']..."
+    >>> browser.open('forms.html')
     >>> form = browser.getForm('2')
     >>> form.getControl('Submit').click()
     >>> browser.contents
-    '...<em>Second Text</em>...'
+    "...'text-value': ['Second Text']..."
+    >>> browser.open('forms.html')
     >>> browser.getForm('3').getControl('Text Control').value
     'Third Text'
 
@@ -1083,10 +993,11 @@
     >>> form = browser.getForm(index=3)
     >>> form.submit()
     >>> browser.contents
-    '...<em>Fourth Text</em>...<em>Submitted without the submit button.</em>...'
+    "...'text-value': ['Fourth Text']..."
 
 If a form is requested that does not exists, an exception will be raised.
 
+    >>> browser.open('forms.html')
     >>> form = browser.getForm('does-not-exist')
     Traceback (most recent call last):
     LookupError
@@ -1094,13 +1005,14 @@
 If the HTML page contains only one form, no arguments to `getForm` are
 needed:
 
-    >>> oneform = Browser()
-    >>> oneform.open('http://localhost/@@/testbrowser/oneform.html')
-    >>> form = oneform.getForm()
+    >>> browser.open('oneform.html')
+    >>> browser.getForm()
+    <zope.testbrowser...Form object at ...>
 
 If the HTML page contains more than one form, `index` is needed to
 disambiguate if no other arguments are provided:
 
+    >>> browser.open('forms.html')
     >>> browser.getForm()
     Traceback (most recent call last):
     ValueError: if no other arguments are given, index is required.
@@ -1114,81 +1026,13 @@
 Be very careful using raw seconds, cross-machine differences can be huge,
 pystones is usually a better choice.
 
-    >>> browser.open('http://localhost/@@/testbrowser/simple.html')
+    >>> browser.open('index.html')
     >>> browser.lastRequestSeconds < 10 # really big number for safety
     True
     >>> browser.lastRequestPystones < 10000 # really big number for safety
     True
 
 
-Handling Errors when using Zope 3's Publisher
----------------------------------------------
-
-A very useful feature of the publisher is the automatic graceful handling of
-application errors, such as invalid URLs:
-
-    >>> browser.open('http://localhost/invalid')
-    Traceback (most recent call last):
-    ...
-    HTTPError: HTTP Error 404: Not Found
-
-Note that the above error was thrown by ``urllib2`` and not by the
-publisher.  For debugging purposes, however, it can be very useful to see the
-original exception caused by the application.  In those cases you can set the
-``handleErrors`` property of the browser to ``False``.  It is defaulted to
-``True``:
-
-    >>> browser.handleErrors
-    True
-
-So when we tell the publisher not to handle the errors,
-
-    >>> browser.handleErrors = False
-
-we get a different, Zope internal error:
-
-    >>> browser.open('http://localhost/invalid')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <zope.app.folder.folder.Folder object at ...>,
-              name: u'invalid'
-
-NB: Setting the handleErrors attribute to False will only change
-    anything if the http server you're testing is using Zope 3's
-    publisher or can otherwise respond appropriately to an
-    'X-zope-handle-errors' header in requests.
-
-When the testbrowser is raising HttpErrors, the errors still hit the test.
-Sometimes we don't want that to happen, in situations where there are edge
-cases that will cause the error to be predictabley but infrequently raised.
-Time is a primary cause of this.
-
-To get around this, one can set the raiseHttpErrors to False.
-
-    >>> browser.handleErrors = True
-    >>> browser.raiseHttpErrors = False
-
-This will cause HttpErrors not to propagate.
-
-    >>> browser.open('http://localhost/invalid')
-
-The headers are still there, though.
-
-    >>> '404 Not Found' in str(browser.headers)
-    True
-
-If we don't handle the errors, and allow internal ones to propagate, however,
-this flage doesn't affect things.
-
-    >>> browser.handleErrors = False
-    >>> browser.open('http://localhost/invalid')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <zope.app.folder.folder.Folder object at ...>,
-              name: u'invalid'
-
-    >>> browser.raiseHttpErrors = True
-
 Hand-Holding
 ------------
 
@@ -1228,7 +1072,7 @@
 When URLs have spaces in them, they're handled correctly (before the bug was
 fixed, you'd get "ValueError: too many values to unpack"):
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
+    >>> browser.open('navigate.html')
     >>> browser.getLink('Spaces in the URL').click()
 
 .goBack() Truncation
@@ -1236,11 +1080,11 @@
 
 The .goBack() method used to truncate the .contents.
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
+    >>> browser.open('navigate.html')
     >>> actual_length = len(browser.contents)
 
-    >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
-    >>> browser.open('http://localhost/@@/testbrowser/simple.html')
+    >>> browser.open('navigate.html')
+    >>> browser.open('index.html')
     >>> browser.goBack()
     >>> len(browser.contents) == actual_length
     True

Added: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/Zope.txt
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/Zope.txt	                        (rev 0)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/Zope.txt	2007-09-17 10:34:53 UTC (rev 79707)
@@ -0,0 +1,67 @@
+Handling Errors when using Zope 3's Publisher
+---------------------------------------------
+
+A very useful feature of the publisher is the automatic graceful handling of
+application errors, such as invalid URLs:
+
+    >>> browser.open('http://localhost/invalid')
+    Traceback (most recent call last):
+    ...
+    HTTPError: HTTP Error 404: Not Found
+
+Note that the above error was thrown by ``urllib2`` and not by the
+publisher.  For debugging purposes, however, it can be very useful to see the
+original exception caused by the application.  In those cases you can set the
+``handleErrors`` property of the browser to ``False``.  It is defaulted to
+``True``:
+
+    >>> browser.handleErrors
+    True
+
+So when we tell the publisher not to handle the errors,
+
+    >>> browser.handleErrors = False
+
+we get a different, Zope internal error:
+
+    >>> browser.open('http://localhost/invalid')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <zope.app.folder.folder.Folder object at ...>,
+              name: u'invalid'
+
+NB: Setting the handleErrors attribute to False will only change
+    anything if the http server you're testing is using Zope 3's
+    publisher or can otherwise respond appropriately to an
+    'X-zope-handle-errors' header in requests.
+
+When the testbrowser is raising HttpErrors, the errors still hit the test.
+Sometimes we don't want that to happen, in situations where there are edge
+cases that will cause the error to be predictabley but infrequently raised.
+Time is a primary cause of this.
+
+To get around this, one can set the raiseHttpErrors to False.
+
+    >>> browser.handleErrors = True
+    >>> browser.raiseHttpErrors = False
+
+This will cause HttpErrors not to propagate.
+
+    >>> browser.open('http://localhost/invalid')
+
+The headers are still there, though.
+
+    >>> '404 Not Found' in str(browser.headers)
+    True
+
+If we don't handle the errors, and allow internal ones to propagate, however,
+this flage doesn't affect things.
+
+    >>> browser.handleErrors = False
+    >>> browser.open('http://localhost/invalid')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <zope.app.folder.folder.Folder object at ...>,
+              name: u'invalid'
+
+    >>> browser.raiseHttpErrors = True


Property changes on: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/Zope.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/browser.py
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/browser.py	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/browser.py	2007-09-17 10:34:53 UTC (rev 79707)
@@ -16,15 +16,17 @@
 $Id$
 """
 __docformat__ = "reStructuredText"
+
+from cStringIO import StringIO
 from zope.testbrowser import interfaces
 import ClientForm
-from cStringIO import StringIO
 import mechanize
 import operator
 import re
 import sys
 import time
 import urllib2
+import urlparse
 
 try:
     from zope import interface
@@ -150,6 +152,7 @@
     """A web user agent."""
     interface.implements(interfaces.IBrowser)
 
+    base = None
     _contents = None
     _counter = 0
 
@@ -218,6 +221,8 @@
 
     def open(self, url, data=None):
         """See zope.testbrowser.interfaces.IBrowser"""
+        if self.base is not None:
+            url = urlparse.urljoin(self.base, url)
         self._start_timer()
         try:
             try:

Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/forms.html
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/forms.html	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/forms.html	2007-09-17 10:34:53 UTC (rev 79707)
@@ -6,26 +6,25 @@
     <em tal:condition="request/text-value|nothing"
         tal:content="request/text-value" />
 
-    <form id="1" name="one" action="forms.html"
-          enctype="multipart/form-data" method="post">
+    <form id="1" name="one" action="forms.html" method="post">
       <input type="text" name="text-value" value="First Text" />
       <input type="image" name="image-1" src="zope3logo.gif" />
       <input type="submit" name="submit-1" value="Submit" />
     </form>
 
-    <form id="2" name="two" action="forms.html">
+    <form id="2" name="two" action="forms.html" method="post">
       <input type="text" name="text-value" value="Second Text" />
       <input type="submit" name="submit-2" value="Submit" />
     </form>
 
-    <form id="3" name="three" action="forms.html">
+    <form id="3" name="three" action="forms.html" method="post">
       <label for="text-value-3">Text Control</label>
       <input type="text" name="text-value" id="text-value-3"
              value="Third Text" />
       <input type="submit" name="submit-3" value="Submit" />
     </form>
 
-    <form action="forms.html">
+    <form action="forms.html" method="post">
       <label for="text-value-4">Text Control</label>
       <input type="text" name="text-value" id="text-value-4"
              value="Fourth Text" />

Copied: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/index.html (from rev 79609, zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/simple.html)
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/index.html	                        (rev 0)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/index.html	2007-09-17 10:34:53 UTC (rev 79707)
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <title>Simple Page</title>
+  </head>
+  <body>
+    <h1>Simple Page</h1>
+  </body>
+</html>

Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/navigate.html
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/navigate.html	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/navigate.html	2007-09-17 10:34:53 UTC (rev 79707)
@@ -7,19 +7,15 @@
       Message: <em tal:content="request/message">Message</em>
     </p>
 
-    <a href="navigate.html?message=By+Link+Text">Link Text</a>
+    <a href="target.html">Link Text</a>
 
-    <a href="navigate.html?message=By+Link+Text+with+Normalization"> Link Text 
+    <a href="target.html"> Link Text 
     with     Whitespace	Normalization (and parens) </a>
 
-    <a href="navigate.html?message=By+URL">Using the URL</a>
+    <a href="target.html" id="anchorid">By Anchor Id</a>
 
-    <a href="navigate.html?message=By+Name" name="anchorname">By Anchor Name</a>
+    <a href="target.html">Spaces in the URL</a>
 
-    <a href="navigate.html?message=By+Id" id="anchorid">By Anchor Id</a>
-
-    <a href="navigate.html?message=Spaces in URL">Spaces in the URL</a>
-
     <form action="navigate.html" method="post">
       <input name="message" value="By Form Submit" />
       <input type="submit" name="submit-form" value="Submit" />
@@ -27,11 +23,11 @@
 
     <img src="./zope3logo.gif" usemap="#zope3logo" />
     <map name="zope3logo">
-      <area shape="rect" alt="Zope3" 
-            href="navigate.html?message=Zope+3+Name" id="zope3" title="Zope 3" 
+      <area shape="rect" alt="Zope3"
+            href="target.html" id="zope3" title="Zope 3"
             coords="44,7,134,33" />
-      <area shape="circle" alt="Logo" 
-            href="navigate.html?message=Logo" id="logo" title="Logo" 
+      <area shape="circle" alt="Logo"
+            href="navigate.html?message=Logo" id="logo" title="Logo"
             coords="23,21,18" />
     </map>
 

Deleted: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/simple.html
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/simple.html	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/simple.html	2007-09-17 10:34:53 UTC (rev 79707)
@@ -1,8 +0,0 @@
-<html>
-  <head>
-    <title>Simple Page</title>
-  </head>
-  <body>
-    <h1>Simple Page</h1>
-  </body>
-</html>

Added: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/target.html
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/target.html	                        (rev 0)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/ftests/target.html	2007-09-17 10:34:53 UTC (rev 79707)
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <title>Target Page</title>
+  </head>
+  <body>
+    This page is the target of a link.
+  </body>
+</html>

Added: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/headers.txt
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/headers.txt	                        (rev 0)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/headers.txt	2007-09-17 10:34:53 UTC (rev 79707)
@@ -0,0 +1,25 @@
+Headers
+-------
+
+As you can see, the `contents` of the browser does not return any HTTP
+headers.  The headers are accessible via a separate attribute, which is an
+``httplib.HTTPMessage`` instance (httplib is a part of Python's standard
+library):
+
+    >>> browser.base = 'http://localhost:%s/' % TEST_PORT
+    >>> browser.open('index.html')
+    >>> browser.headers
+    <httplib.HTTPMessage instance...>
+
+The headers can be accessed as a string:
+
+    >>> print browser.headers
+    Server: BaseHTTP/0.3 Python/2.4.4
+    Date: Mon, 17 Sep 2007 10:05:42 GMT
+    Connection: close
+    Content-type: text/html
+
+Or as a mapping:
+
+    >>> browser.headers['content-type']
+    'text/html'


Property changes on: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/headers.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/tests.py
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/tests.py	2007-09-17 07:18:31 UTC (rev 79706)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/tests.py	2007-09-17 10:34:53 UTC (rev 79707)
@@ -17,19 +17,72 @@
 """
 
 from cStringIO import StringIO
-from zope.app.testing import functional
-from zope.app.testing.functional import FunctionalDocFileSuite
 from zope.testbrowser import browser
 from zope.testing import renormalizing, doctest
+import BaseHTTPServer
+import cgi
 import httplib
 import mechanize
-import os
+import os.path
+import pprint
+import random
 import re
+import string
+import threading
 import unittest
-import unittest
+import urllib
 import urllib2
+import zope.testbrowser.browser
 
+try:
+    from zope.app.testing import functional
+except:
+    functional = None
 
+web_server_base_path = os.path.join(os.path.split(__file__)[0], 'ftests')
+
+class TestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+
+    def date_time_string(self):
+        return 'Mon, 17 Sep 2007 10:05:42 GMT'
+
+    def do_GET(self):
+        if self.path.endswith('robots.txt'):
+            self.send_response(404)
+            self.send_header('Connection', 'close')
+            return
+
+        try:
+            f = open(web_server_base_path + self.path)
+        except IOError:
+            self.send_response(500)
+            self.send_header('Connection', 'close')
+            return
+
+        self.send_response(200)
+        self.send_header('Connection', 'close')
+        if self.path.endswith('.gif'):
+            self.send_header('Content-type', 'image/gif')
+        else:
+            self.send_header('Content-type', 'text/html')
+
+        self.end_headers()
+        self.wfile.write(f.read())
+        f.close()
+
+    def do_POST(self):
+        body = self.rfile.read(int(self.headers['content-length']))
+        values = cgi.parse_qs(body)
+        self.wfile
+        self.send_response(200)
+        self.send_header('Content-type', 'text/plain')
+        self.end_headers()
+        pprint.pprint(values, self.wfile)
+
+    def log_request(self, *args, **kws):
+        pass
+
+
 def set_next_response(body, headers=None, status='200', reason='OK'):
     global next_response_body
     global next_response_headers
@@ -376,20 +429,55 @@
     (re.compile(r'Content-Type: '), 'Content-type: '),
     ])
 
-TestBrowserLayer = functional.ZCMLLayer(
-    os.path.join(os.path.split(__file__)[0], 'ftests/ftesting.zcml'),
-    __name__, 'TestBrowserLayer', allow_teardown=True)
+def serve_requests(server):
+    global server_stopped
+    global server_stop
+    server_stop = False
+    while not server_stop:
+        server.handle_request()
+    server.socket.close()
 
+def setUpServer(test):
+    port = random.randint(20000,30000)
+    test.globs['TEST_PORT'] = port
+    server = BaseHTTPServer.HTTPServer(('localhost', port), TestHandler)
+    thread = threading.Thread(target=serve_requests, args=[server])
+    thread.setDaemon(True)
+    thread.start()
+    test.globs['web_server_thread'] = thread
+
+def tearDownServer(test):
+    global server_stop
+    server_stop = True
+    # make a request, so the last call to `handle_one_request` will return
+    urllib.urlretrieve('http://localhost:%d/' % test.globs['TEST_PORT'])
+    test.globs['web_server_thread'].join()
+
+def setUpWire(test):
+    test.globs['Browser'] = zope.testbrowser.browser.Browser
+    setUpServer(test)
+
+def tearDownWire(test):
+    tearDownServer(test)
+
+def setUpHeaders(test):
+    setUpServer(test)
+    test.globs['browser'] = zope.testbrowser.browser.Browser()
+
+def tearDownHeaders(test):
+    tearDownServer(test)
+
 def test_suite():
     flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
-    readme = FunctionalDocFileSuite('README.txt', optionflags=flags,
-        checker=checker)
-    readme.layer = TestBrowserLayer
-    wire = doctest.DocFileSuite('over_the_wire.txt', optionflags=flags)
-    wire.level = 2
+
+    readme = doctest.DocFileSuite('README.txt', optionflags=flags,
+        checker=checker, setUp=setUpWire, tearDown=tearDownWire)
+
+    headers = doctest.DocFileSuite('headers.txt', optionflags=flags,
+        setUp=setUpHeaders, tearDown=tearDownHeaders)
+
     this_file = doctest.DocTestSuite(checker=checker)
-    return unittest.TestSuite((this_file, readme, wire))
+    return unittest.TestSuite((this_file, readme, headers))
 
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')
-

Copied: zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/zopetests.py (from rev 79613, zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/tests.py)
===================================================================
--- zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/zopetests.py	                        (rev 0)
+++ zope.testbrowser/branches/benji-reduce-testing-dependencies/src/zope/testbrowser/zopetests.py	2007-09-17 10:34:53 UTC (rev 79707)
@@ -0,0 +1,43 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Real test for file-upload and beginning of a better internal test framework
+
+$Id$
+"""
+
+from zope.testing import doctest
+import os.path
+import unittest
+import zope.app.testing.functional
+import zope.testbrowser.testing
+import zope.testbrowser.tests
+
+TestBrowserLayer = zope.app.testing.functional.ZCMLLayer(
+    os.path.join(os.path.split(__file__)[0], 'ftests/ftesting.zcml'),
+    __name__, 'TestBrowserLayer', allow_teardown=True)
+
+def setUp(test):
+    test.globs['browser'] = zope.testbrowser.testing.Browser()
+
+def test_suite():
+    flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
+
+    readme = zope.app.testing.functional.FunctionalDocFileSuite('Zope.txt',
+        optionflags=flags, checker=zope.testbrowser.tests.checker, setUp=setUp)
+    readme.layer = TestBrowserLayer
+
+    return unittest.TestSuite((readme,))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')



More information about the Checkins mailing list