[Checkins] SVN: zc.testbrowser/trunk/src/zc/testbrowser/ - renamed waitForPageLoad() to wait()

Benji York benji at zope.com
Tue Feb 26 23:11:57 EST 2008


Log message for revision 84315:
  - renamed waitForPageLoad() to wait()
  - added wait() to IBrowser and implementations; having an explicit "wait for
    the page to load" call seems to work much better (for example, some
    link.click()s trigger a page load and some don't, now we don't have to guess
    if we need to wait or not)
  - separated out some interfaces out of IBrowser
  - made zc.testbrowser.real not pretend to implement anything but, the now
    smaller, IBrowser
  - use modern import style
  

Changed:
  U   zc.testbrowser/trunk/src/zc/testbrowser/README.txt
  U   zc.testbrowser/trunk/src/zc/testbrowser/browser.py
  U   zc.testbrowser/trunk/src/zc/testbrowser/interfaces.py
  A   zc.testbrowser/trunk/src/zc/testbrowser/performance.txt
  U   zc.testbrowser/trunk/src/zc/testbrowser/real.py
  U   zc.testbrowser/trunk/src/zc/testbrowser/screen-shots.txt
  U   zc.testbrowser/trunk/src/zc/testbrowser/tests.py

-=-
Modified: zc.testbrowser/trunk/src/zc/testbrowser/README.txt
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/README.txt	2008-02-27 03:27:20 UTC (rev 84314)
+++ zc.testbrowser/trunk/src/zc/testbrowser/README.txt	2008-02-27 04:11:56 UTC (rev 84315)
@@ -23,6 +23,8 @@
     >>> from zope.interface.verify import verifyObject
     >>> zc.testbrowser.interfaces.IBrowser.providedBy(browser)
     True
+    >>> verifyObject(zc.testbrowser.interfaces.IBrowser, browser)
+    True
 
 
 Page Contents
@@ -128,6 +130,7 @@
 Links can be "clicked" and the browser will navigate to the referenced URL.
 
     >>> link.click()
+    >>> browser.wait()
     >>> browser.url
     'http://localhost:.../target.html'
     >>> browser.contents
@@ -145,6 +148,7 @@
     >>> link.text
     'Link Text with Whitespace Normalization (and parens)'
     >>> link.click()
+    >>> browser.wait()
     >>> browser.url
     'http://localhost:.../target.html'
 
@@ -171,6 +175,7 @@
 
     >>> browser.open('navigate.html')
     >>> browser.getLink(url='target.html').click()
+    >>> browser.wait()
     >>> browser.url
     'http://localhost:.../target.html'
 
@@ -181,6 +186,7 @@
     '...<a href="target.html" id="anchorid">By Anchor Id</a>...'
 
     >>> browser.getLink(id='anchorid').click()
+    >>> browser.wait()
     >>> browser.url
     'http://localhost:.../target.html'
 
@@ -191,6 +197,7 @@
     >>> browser.open('navigate.html')
     >>> link = browser.getLink(id='zope3')
     >>> link.click()
+    >>> browser.wait()
     >>> browser.url
     'http://localhost:.../target.html'
 
@@ -892,6 +899,7 @@
 
     >>> browser.getControl('Text Control').value = 'Other Text'
     >>> browser.getControl('Submit').click()
+    >>> browser.wait()
     >>> browser.contents
     "...'text-value': ['Other Text']..."
 
@@ -911,6 +919,7 @@
     >>> browser.open('controls.html')
     >>> browser.getControl('Text Control').value = 'Other Text'
     >>> browser.getControl(name='image-value').click()
+    >>> browser.wait()
     >>> browser.contents
     "...'text-value': ['Other Text']..."
 
@@ -1015,6 +1024,7 @@
     >>> browser.open('forms.html')
     >>> form = browser.getForm('2')
     >>> form.getControl('Submit').click()
+    >>> browser.wait()
     >>> browser.contents
     "...'text-value': ['Second Text']..."
     >>> browser.open('forms.html')
@@ -1053,21 +1063,6 @@
     ValueError: if no other arguments are given, index is required.
 
 
-Performance Testing
--------------------
-
-Browser objects keep up with how much time each request takes.  This can be
-used to ensure a particular request's performance is within a tolerable range.
-Be very careful using raw seconds, cross-machine differences can be huge,
-pystones is usually a better choice.
-
-    >>> browser.open('index.html')
-    >>> browser.lastRequestSeconds < 10 # really big number for safety
-    True
-    >>> browser.lastRequestPystones < 100000 # really big number for safety
-    True
-
-
 Hand-Holding
 ------------
 
@@ -1109,6 +1104,7 @@
 
     >>> browser.open('navigate.html')
     >>> browser.getLink('Spaces in the URL').click()
+    >>> browser.wait()
 
 .goBack() Truncation
 ~~~~~~~~~~~~~~~~~~~~

Modified: zc.testbrowser/trunk/src/zc/testbrowser/browser.py
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/browser.py	2008-02-27 03:27:20 UTC (rev 84314)
+++ zc.testbrowser/trunk/src/zc/testbrowser/browser.py	2008-02-27 04:11:56 UTC (rev 84315)
@@ -142,8 +142,11 @@
 
 class Browser(SetattrErrorsMixin):
     """A web user agent."""
-    zope.interface.implements(zc.testbrowser.interfaces.IBrowser)
 
+    zope.interface.implements(zc.testbrowser.interfaces.IBrowser,
+        zc.testbrowser.interfaces.IHeaders,
+        zc.testbrowser.interfaces.ITiming)
+
     base = None
     _contents = None
     _counter = 0
@@ -368,7 +371,10 @@
         self._counter += 1
         self._contents = None
 
+    def wait(self):
+        pass # no need to wait for this browser type
 
+
 class Link(SetattrErrorsMixin):
     zope.interface.implements(zc.testbrowser.interfaces.ILink)
 

Modified: zc.testbrowser/trunk/src/zc/testbrowser/interfaces.py
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/interfaces.py	2008-02-27 03:27:20 UTC (rev 84314)
+++ zc.testbrowser/trunk/src/zc/testbrowser/interfaces.py	2008-02-27 04:11:56 UTC (rev 84315)
@@ -13,63 +13,42 @@
 ##############################################################################
 __docformat__ = "reStructuredText"
 
-from zope import interface, schema
+import zope.interface
+import zope.schema
 
 
 class LinkNotFoundError(ValueError):
-    """Exception raised if a link could not be found for the given parameter."""
+    """Exception raised if a link could not be found for the given parameter"""
 
 
-class IBrowser(interface.Interface):
-    """A Programmatic Web Browser."""
+class IBrowser(zope.interface.Interface):
+    """A Programmatic Web Browser"""
 
-    url = schema.URI(
+    url = zope.schema.URI(
         title=u"URL",
         description=u"The URL the browser is currently showing.",
         required=True)
 
-    headers = schema.Field(
-        title=u"Headers",
-        description=(u"Headers of the HTTP response; a "
-                     "``httplib.HTTPMessage``."),
-        required=True)
-
-    contents = schema.Text(
+    contents = zope.schema.Text(
         title=u"Contents",
         description=u"The complete response body of the HTTP request.",
         required=True)
 
-    isHtml = schema.Bool(
+    isHtml = zope.schema.Bool(
         title=u"Is HTML",
         description=u"Tells whether the output is HTML or not.",
         required=True)
 
-    title = schema.TextLine(
+    title = zope.schema.TextLine(
         title=u"Base",
         description=u"Base URL for opening relative paths",
         required=False)
 
-    title = schema.TextLine(
+    title = zope.schema.TextLine(
         title=u"Title",
         description=u"Title of the displayed page",
         required=False)
 
-    handleErrors = schema.Bool(
-        title=u"Handle Errors",
-        description=(u"Describes whether server-side errors will be handled "
-                     u"by the publisher. If set to ``False``, the error will "
-                     u"progress all the way to the test, which is good for "
-                     u"debugging."),
-        default=True,
-        required=True)
-
-    def addHeader(key, value):
-        """Adds a header to each HTTP request.
-
-        Adding additional headers can be useful in many ways, from setting the
-        credentials token to specifying the browser identification string.
-        """
-
     def open(url, data=None):
         """Open a URL in the browser.
 
@@ -108,29 +87,6 @@
           o ``id`` -- The id attribute of the anchor tag submit button.
         """
 
-    lastRequestSeconds = schema.Field(
-        title=u"Seconds to Process Last Request",
-        description=(
-        u"""Return how many seconds (or fractions) the last request took.
-
-        The values returned have the same resolution as the results from
-        ``time.clock``.
-        """),
-        required=True,
-        readonly=True)
-
-    lastRequestPystones = schema.Field(
-        title=
-            u"Approximate System-Independent Effort of Last Request (Pystones)",
-        description=(
-        u"""Return how many pystones the last request took.
-
-        This number is found by multiplying the number of pystones/second at
-        which this system benchmarks and the result of ``lastRequestSeconds``.
-        """),
-        required=True,
-        readonly=True)
-
     def getControl(label=None, name=None, index=None):
         """Get a control from the page.
 
@@ -167,38 +123,106 @@
         """
 
 
+class IWait(zope.interface.Interface):
+    """Wait for asynchronous events"""
+
+    def wait():
+        """Wait for a page load to complete.
+
+        Any action that causes a page load must be complete before more browser
+        actions are executed.
+        """
+
+
+class IHeaders(zope.interface.Interface):
+    """Expose HTTP headers and the manipulation thereof"""
+
+    headers = zope.schema.Field(
+        title=u"Headers",
+        description=(u"Headers of the HTTP response; a "
+                     "``httplib.HTTPMessage``."),
+        required=True)
+
+    def addHeader(key, value):
+        """Adds a header to each HTTP request.
+
+        Adding additional headers can be useful in many ways, from setting the
+        credentials token to specifying the browser identification string.
+        """
+
+
+class ITiming(zope.interface.Interface):
+    """Keep up with how long requests take in seconds and pystones"""
+
+    lastRequestSeconds = zope.schema.Field(
+        title=u"Seconds to Process Last Request",
+        description=(
+        u"""Return how many seconds (or fractions) the last request took.
+
+        The values returned have the same resolution as the results from
+        ``time.clock``.
+        """),
+        required=True,
+        readonly=True)
+
+    lastRequestPystones = zope.schema.Field(
+        title=
+            u"Approximate System-Independent Effort of Last Request (Pystones)",
+        description=(
+        u"""Return how many pystones the last request took.
+
+        This number is found by multiplying the number of pystones/second at
+        which this system benchmarks and the result of ``lastRequestSeconds``.
+        """),
+        required=True,
+        readonly=True)
+
+
+class IZopeBrowser(IBrowser, IHeaders, ITiming):
+    """A browser for use with the Zope functional testing framework"""
+
+    handleErrors = zope.schema.Bool(
+        title=u"Handle Errors",
+        description=(u"Describes whether server-side errors will be handled "
+                     u"by the publisher. If set to ``False``, the error will "
+                     u"progress all the way to the test, which is good for "
+                     u"debugging."),
+        default=True,
+        required=True)
+
+
 class ExpiredError(Exception):
     """The browser page to which this was attached is no longer active"""
 
 
-class IControl(interface.Interface):
+class IControl(zope.interface.Interface):
     """A control (input field) of a page."""
 
-    name = schema.TextLine(
+    name = zope.schema.TextLine(
         title=u"Name",
         description=u"The name of the control.",
         required=True)
 
-    value = schema.Field(
+    value = zope.schema.Field(
         title=u"Value",
         description=u"The value of the control",
         default=None,
         required=True)
 
-    type = schema.Choice(
+    type = zope.schema.Choice(
         title=u"Type",
         description=u"The type of the control",
         values=['text', 'password', 'hidden', 'submit', 'checkbox', 'select',
                 'radio', 'image', 'file'],
         required=True)
 
-    disabled = schema.Bool(
+    disabled = zope.schema.Bool(
         title=u"Disabled",
         description=u"Describes whether a control is disabled.",
         default=False,
         required=False)
 
-    multiple = schema.Bool(
+    multiple = zope.schema.Bool(
         title=u"Multiple",
         description=u"Describes whether this control can hold multiple values.",
         default=False,
@@ -211,20 +235,20 @@
 class IListControl(IControl):
     """A radio button, checkbox, or select control"""
 
-    options = schema.List(
+    options = zope.schema.List(
         title=u"Options",
         description=u"""\
         A list of possible values for the control.""",
         required=True)
 
-    displayOptions = schema.List(
+    displayOptions = zope.schema.List(
         # TODO: currently only implemented for select by ClientForm
         title=u"Options",
         description=u"""\
         A list of possible display values for the control.""",
         required=True)
 
-    displayValue = schema.Field(
+    displayValue = zope.schema.Field(
         # TODO: currently only implemented for select by ClientForm
         title=u"Value",
         description=u"The value of the control, as rendered by the display",
@@ -238,7 +262,7 @@
         'Add a contact' but not 'Address'.  A word is defined as one or more
         alphanumeric characters or the underline."""
 
-    controls = interface.Attribute(
+    controls = zope.interface.Attribute(
         """a list of subcontrols for the control.  mutating list has no effect
         on control (although subcontrols may be changed as usual).""")
 
@@ -255,65 +279,65 @@
         "click the submit button with optional coordinates"
 
 
-class IItemControl(interface.Interface):
+class IItemControl(zope.interface.Interface):
     """a radio button or checkbox within a larger multiple-choice control"""
 
-    control = schema.Object(
+    control = zope.schema.Object(
         title=u"Control",
         description=(u"The parent control element."),
         schema=IControl,
         required=True)
 
-    disabled = schema.Bool(
+    disabled = zope.schema.Bool(
         title=u"Disabled",
         description=u"Describes whether a subcontrol is disabled.",
         default=False,
         required=False)
 
-    selected = schema.Bool(
+    selected = zope.schema.Bool(
         title=u"Selected",
         description=u"Whether the subcontrol is selected",
         default=None,
         required=True)
 
-    optionValue = schema.TextLine(
+    optionValue = zope.schema.TextLine(
         title=u"Value",
         description=u"The value of the subcontrol",
         default=None,
         required=False)
 
 
-class ILink(interface.Interface):
+class ILink(zope.interface.Interface):
 
     def click():
         """click the link, going to the URL referenced"""
 
-    url = schema.TextLine(
+    url = zope.schema.TextLine(
         title=u"URL",
         description=u"The normalized URL of the link",
         required=False)
 
-    text = schema.TextLine(
+    text = zope.schema.TextLine(
         title=u'Text',
         description=u'The contained text of the link',
         required=False)
 
 
-class IForm(interface.Interface):
-    """An HTML form of the page."""
+class IForm(zope.interface.Interface):
+    """An HTML form of the page"""
 
-    action = schema.TextLine(
+    action = zope.schema.TextLine(
         title=u"Action",
         description=u"The action (or URI) that is opened upon submittance.",
         required=True)
 
-    name = schema.TextLine(
+    name = zope.schema.TextLine(
         title=u"Name",
         description=u"The value of the `name` attribute in the form tag, "
                     u"if specified.",
         required=True)
 
-    id = schema.TextLine(
+    id = zope.schema.TextLine(
         title=u"Id",
         description=u"The value of the `id` attribute in the form tag, "
                     u"if specified.",
@@ -355,5 +379,6 @@
         filtered to find only submit and image controls.
         """
 
+
 class ITextAreaControl(IControl):
-    """An HTML text area.  Mostly just a marker."""
+    """An HTML text area.  Mostly just a marker"""

Added: zc.testbrowser/trunk/src/zc/testbrowser/performance.txt
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/performance.txt	                        (rev 0)
+++ zc.testbrowser/trunk/src/zc/testbrowser/performance.txt	2008-02-27 04:11:56 UTC (rev 84315)
@@ -0,0 +1,14 @@
+Performance Testing
+-------------------
+
+Browser objects keep up with how much time each request takes.  This can be
+used to ensure a particular request's performance is within a tolerable range.
+Be very careful using raw seconds, cross-machine differences can be huge,
+pystones is usually a better choice.
+
+    >>> browser.base = 'http://localhost:%s/' % TEST_PORT
+    >>> browser.open('index.html')
+    >>> browser.lastRequestSeconds < 10 # really big number for safety
+    True
+    >>> browser.lastRequestPystones < 100000 # really big number for safety
+    True


Property changes on: zc.testbrowser/trunk/src/zc/testbrowser/performance.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: zc.testbrowser/trunk/src/zc/testbrowser/real.py
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/real.py	2008-02-27 03:27:20 UTC (rev 84314)
+++ zc.testbrowser/trunk/src/zc/testbrowser/real.py	2008-02-27 04:11:56 UTC (rev 84315)
@@ -56,9 +56,11 @@
 
     return Control(token, browser)
 
+
 def any(items):
     return bool(sum([bool(i) for i in items]))
 
+
 class JSFunctionProxy(object):
     def __init__(self, executor, name):
         self.executor = executor
@@ -90,8 +92,10 @@
 
 
 class Browser(zc.testbrowser.browser.SetattrErrorsMixin):
-    zope.interface.implements(zc.testbrowser.interfaces.IBrowser)
 
+    zope.interface.implements(zc.testbrowser.interfaces.IBrowser,
+        zc.testbrowser.interfaces.IWait)
+
     base = None
     raiseHttpErrors = True
     _counter = 0
@@ -99,7 +103,6 @@
 
     def __init__(self, url=None, host='localhost', port=4242):
         self.js = JSProxy(self.execute)
-        self.timer = zc.testbrowser.browser.PystoneTimer()
         self.init_repl(host, port)
         self._enable_setattr_errors = True
 
@@ -158,25 +161,25 @@
     def url(self):
         return self.execute('content.location')
 
-    def waitForPageLoad(self):
+    def wait(self):
         start = time.time()
         while self.execute('tb_page_loaded') == 'false':
             time.sleep(0.001)
             if time.time() - start > self.timeout:
                 raise RuntimeError('timed out waiting for page load')
 
+        assert self.execute('tb_page_loaded;') == 'true'
         self.execute('tb_page_loaded = false;')
+        assert self.execute('tb_page_loaded;') == 'false'
 
     def open(self, url, data=None):
         if self.base is not None:
             url = urlparse.urljoin(self.base, url)
         assert data is None
-        self.start_timer()
         try:
             self.execute('content.location = ' + simplejson.dumps(url))
-            self.waitForPageLoad()
+            self.wait()
         finally:
-            self.stop_timer()
             self._changed()
 
         # TODO raise non-200 errors
@@ -203,52 +206,17 @@
                 "content.document.getElementsByTagName('pre')[0].innerHTML")
         return self.execute('content.document.documentElement.innerHTML')
 
-    @property
-    def headers(self):
-        raise NotImplementedError
-
-    @apply
-    def handleErrors():
-        def get(self):
-            raise NotImplementedError
-
-        def set(self, value):
-            raise NotImplementedError
-
-        return property(get, set)
-
-    def start_timer(self):
-        self.timer.start()
-
-    def stop_timer(self):
-        self.timer.stop()
-
-    @property
-    def lastRequestPystones(self):
-        return self.timer.elapsedPystones
-
-    @property
-    def lastRequestSeconds(self):
-        return self.timer.elapsedSeconds
-
     def reload(self):
-        self.start_timer()
         self.execute('content.document.location = content.document.location')
-        self.waitForPageLoad()
-        self.stop_timer()
+        self.wait()
 
     def goBack(self, count=1):
-        self.start_timer()
         self.execute('content.back()')
         # Our method of knowing when the page finishes loading doesn't work
         # for "back", so for now just sleep a little, and hope it is enough.
         time.sleep(1)
-        self.stop_timer()
         self._changed()
 
-    def addHeader(self, key, value):
-        raise NotImplementedError
-
     def getLink(self, text=None, url=None, id=None, index=0):
         zc.testbrowser.browser.onlyOne((text, url, id), 'text, url, or id')
         js_index = simplejson.dumps(index)
@@ -269,10 +237,6 @@
 
         return Link(token, self)
 
-    def _follow_link(self, token):
-        self.js.tb_follow_link(token)
-        self.waitForPageLoad()
-
     def getControlToken(self, label=None, name=None, index=None,
                         context_token=None, xpath=None):
         js_index = simplejson.dumps(index)
@@ -348,9 +312,7 @@
     def click(self):
         if self._browser_counter != self.browser._counter:
             raise zc.testbrowser.interfaces.ExpiredError
-        self.browser.start_timer()
-        self.browser._follow_link(self.token)
-        self.browser.stop_timer()
+        self.browser.js.tb_click_token(self.token)
         self.browser._changed()
 
     @property
@@ -687,8 +649,6 @@
         if self._browser_counter != self.browser._counter:
             raise zc.testbrowser.interfaces.ExpiredError
 
-        self.browser.start_timer()
-
         if (label is None and
             name is None):
             self.browser.execute('tb_tokens[%s].submit()' % self.token)
@@ -696,7 +656,6 @@
             button = self.browser.getControlToken(
                 label, name, index, self.token)
             self.browser.js.tb_click_token(button, *coord)
-        self.browser.stop_timer()
         self.browser._changed()
 
     def getControl(self, label=None, name=None, index=None):

Modified: zc.testbrowser/trunk/src/zc/testbrowser/screen-shots.txt
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/screen-shots.txt	2008-02-27 03:27:20 UTC (rev 84314)
+++ zc.testbrowser/trunk/src/zc/testbrowser/screen-shots.txt	2008-02-27 04:11:56 UTC (rev 84315)
@@ -1,4 +1,4 @@
     >>> from zc.testbrowser.real import Browser
     >>> browser = Browser()
-    >>> browser.open('http://slashdot.org')
+    >>> browser.open('http://localhost:%s/index.html' % TEST_PORT)
     >>> browser.execute('tb_take_screen_shot("/tmp/1.png")')

Modified: zc.testbrowser/trunk/src/zc/testbrowser/tests.py
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/tests.py	2008-02-27 03:27:20 UTC (rev 84314)
+++ zc.testbrowser/trunk/src/zc/testbrowser/tests.py	2008-02-27 04:11:56 UTC (rev 84315)
@@ -437,7 +437,7 @@
 def setUpServer(test):
     global server_stop
     server_stop = False
-    port = random.randint(20000,30000)
+    port = random.randint(20000, 30000)
     test.globs['TEST_PORT'] = port
     server = BaseHTTPServer.HTTPServer(('localhost', port), TestHandler)
     thread = threading.Thread(target=serve_requests, args=[server])
@@ -459,42 +459,38 @@
     test.globs['Browser'] = zc.testbrowser.real.Browser
     setUpServer(test)
 
-def tearDownReal(test):
-    tearDownServer(test)
-
-def setUpReadme(test):
+def setUpBrowserClass(test):
     test.globs['Browser'] = zc.testbrowser.browser.Browser
     setUpServer(test)
 
-def tearDownReadme(test):
-    tearDownServer(test)
-
-def setUpHeaders(test):
-    setUpServer(test)
+def setUpBrowserInstance(test):
     test.globs['browser'] = zc.testbrowser.browser.Browser()
+    setUpServer(test)
 
-def tearDownHeaders(test):
-    tearDownServer(test)
-
 def test_suite():
     flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
 
     readme = doctest.DocFileSuite('README.txt', optionflags=flags,
-        checker=checker, setUp=setUpReadme, tearDown=tearDownReadme)
+        checker=checker, setUp=setUpBrowserClass, tearDown=tearDownServer)
 
     headers = doctest.DocFileSuite('headers.txt', optionflags=flags,
-        setUp=setUpHeaders, tearDown=tearDownHeaders)
+        setUp=setUpBrowserInstance, tearDown=tearDownServer)
 
+    performance = doctest.DocFileSuite('performance.txt', optionflags=flags,
+        setUp=setUpBrowserInstance, tearDown=tearDownServer)
+
     real_readme = doctest.DocFileSuite('README.txt', optionflags=flags,
-        checker=checker, setUp=setUpReal, tearDown=tearDownReal)
+        checker=checker, setUp=setUpReal, tearDown=tearDownServer)
     real_readme.level = 3
 
-    screen_shots = doctest.DocFileSuite('screen-shots.txt', optionflags=flags)
+    screen_shots = doctest.DocFileSuite('screen-shots.txt', optionflags=flags,
+        setUp=setUpServer, tearDown=tearDownServer)
     screen_shots.level = 3
 
     this_file = doctest.DocTestSuite(checker=checker)
 
-    return unittest.TestSuite((this_file, readme, real_readme, screen_shots))
+    return unittest.TestSuite((this_file, readme, real_readme, headers,
+        performance, screen_shots))
 
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')



More information about the Checkins mailing list