summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-12-24 00:25:11 +0000
committerChris McDonough <chrism@agendaless.com>2009-12-24 00:25:11 +0000
commitf0c7d07c9532c51f7eb354257ff3563ebba91cf2 (patch)
tree7596cbb5f3916801786e14ec367c826db6da1e57 /docs
parentdae1d57789e60f783497e10e089e4e0669c42b79 (diff)
downloadpyramid-f0c7d07c9532c51f7eb354257ff3563ebba91cf2.tar.gz
pyramid-f0c7d07c9532c51f7eb354257ff3563ebba91cf2.tar.bz2
pyramid-f0c7d07c9532c51f7eb354257ff3563ebba91cf2.zip
Roles.
Diffstat (limited to 'docs')
-rw-r--r--docs/narr/unittesting.rst134
1 files changed, 73 insertions, 61 deletions
diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst
index e49221b78..316142c08 100644
--- a/docs/narr/unittesting.rst
+++ b/docs/narr/unittesting.rst
@@ -40,10 +40,10 @@ measure of assurance that your "units" work together, as they will be
expected to when your application is run in production.
The suggested mechanism for unit and integration testing of a
-:mod:`repoze.bfg` application is the Python ``unittest`` module.
-Although this module is named ``unittest``, it is actually capable of
-driving both unit and integration tests. A good ``unittest`` tutorial
-is available within `Dive Into Python
+:mod:`repoze.bfg` application is the Python :mod:`unittest` module.
+Although this module is named :mod:`unittest`, it is actually capable
+of driving both unit and integration tests. A good :mod:`unittest`
+tutorial is available within `Dive Into Python
<http://diveintopython.org/unit_testing/index.html>`_ by Mark Pilgrim.
:mod:`repoze.bfg` provides a number of facilities that make unit and
@@ -59,8 +59,8 @@ Test Set Up and Tear Down
:mod:`repoze.bfg` uses a "global" (actually :term:`thread local`) data
structure to hold on to two items: the current :term:`request` and the
current :term:`application registry`. These data structures are
-available via the ``repoze.bfg.threadlocal.get_current_request`` and
-``repoze.bfg.threadlocal.get_current_registry`` functions,
+available via the :func:`repoze.bfg.threadlocal.get_current_request`
+and :func:`repoze.bfg.threadlocal.get_current_registry` functions,
respectively. See :ref:`threadlocals_chapter` for information about
these functions and the data structures they return.
@@ -91,20 +91,23 @@ of a single test. Here's an example of using this feature:
self.config.end()
The above will make sure that
-``repoze.bfg.threadlocal.get_current_registry`` will return the
+:func:`repoze.bfg.threadlocal.get_current_registry` will return the
:term:`application registry` associated with the ``config``
-Configurator instance when ``get_current_registry`` is called in a
+Configurator instance when
+:func:`repoze.bfg.threadlocal.get_current_registry` is called in a
test case method attached to ``MyTest``. Each test case method
attached to ``MyTest`` will use an isolated registry.
-The ``begin`` method of a Configurator accepts various arguments that
-influence the code run during the test. See the
-:ref:`configuration_module` chapter for information about the API of a
-:term:`Configurator`, including its ``begin`` and ``end`` methods.
+The :meth:`repoze.bfg.configuration.Configurator.begin` method accepts
+various arguments that influence the code run during the test. See
+the :ref:`configuration_module` chapter for information about the API
+of a :term:`Configurator`, including its ``begin`` and ``end``
+methods.
-If you also want to make ``repoze.bfg.get_current_registry`` return
-something other than ``None`` during the course of a single test, you
-can pass a :term:`request` object into the ``begin`` method of the
+If you also want to make :func:`repoze.bfg.get_current_registry`
+return something other than ``None`` during the course of a single
+test, you can pass a :term:`request` object into the
+:meth:`repoze.bfg.configuration.Configurator.begin` method of the
Configurator within the ``setUp`` method of your test:
.. code-block:: python
@@ -123,15 +126,15 @@ Configurator within the ``setUp`` method of your test:
def tearDown(self):
self.config.end()
-If you pass a term:`Request` object into the ``begin`` method of the
+If you pass a term:`request` object into the ``begin`` method of the
configurator within your test case's ``setUp``, any test method
attached to the ``MyTest`` test case that directly or indirectly calls
-``get_current_request`` will receive the request you passed into the
-``begin`` method. Otherwise, during testing, ``get_current_request``
-will return ``None``. We use a "dummy" request implementation
-supplied by ``repoze.bfg.testing.DummyRequest`` because it's easier to
-construct than a "real" :mod:`repoze.bfg` request object. See
-:ref:`testing_module` for documentation about a DummyRequest.
+:func:`repoze.bfg.threadlocal.get_current_request` will receive the
+request you passed into the ``begin`` method. Otherwise, during
+testing, :func:`repoze.bfg.threadlocal.get_current_request` will
+return ``None``. We use a "dummy" request implementation supplied by
+:class:`repoze.bfg.testing.DummyRequest` because it's easier to
+construct than a "real" :mod:`repoze.bfg` request object.
What?
~~~~~
@@ -139,9 +142,10 @@ What?
Thread local data structures are always a bit confusing, especially
when used by frameworks. Sorry. So here's a rule of thumb: if you
don't *know* whether you're calling code that uses the
-``get_current_registry`` or ``get_current_request`` functions, or you
+:func:`repoze.bfg.threadlocal.get_current_registry` or
+:func:`repoze.bfg.threadlocal.get_current_request` functions, or you
don't care about any of this, but you still want to write test code,
-just always create a configurator instance and call its ``begin``
+just always create a Configurator instance and call its ``begin``
method within the ``setUp`` of a unit test, then subsequently call its
``end`` method in the test's ``tearDown``. This won't really hurt
anything if the application you're testing does not call any
@@ -177,17 +181,18 @@ a :term:`application registry` using :term:`configuration declaration`
calls made against a :term:`Configurator` (sometimes deferring to the
application's ``configure.zcml`` :term:`ZCML` file via ``load_zcml``).
But if this application registry is not created and populated
-(e.g. with an ``add_view`` :term:`configuration declaration` or
-``view`` declarations in :term:`ZCML`), like when you invoke
-application code via a unit test, :mod:`repoze.bfg` API functions will
-tend to fail.
+(e.g. with an :meth:`repoze.bfg.configuration.Configurator.add_view`
+:term:`configuration declaration` or ``view`` declarations in
+:term:`ZCML`), like when you invoke application code via a unit test,
+:mod:`repoze.bfg` API functions will tend to fail.
-The testing API provided by ``repoze.bfg`` allows you to simulate
+The testing API provided by :mod:`repoze.bfg` allows you to simulate
various application registry registrations for use under a unit
testing framework without needing to invoke the actual application
configuration implied by its ``run.py``. For example, if you wanted
-to test the above ``view_fn`` (assuming it lived in ``my.package``),
-you could write a unittest TestCase that used the testing API.
+to test the above ``view_fn`` (assuming it lived in the package named
+``my.package``), you could write a :class:`unittest.TestCase` that
+used the testing API.
.. code-block:: python
:linenos:
@@ -220,7 +225,7 @@ you could write a unittest TestCase that used the testing API.
renderer.assert_(say='Yo')
In the above example, we create a ``MyTest`` test case that inherits
-from ``unittest.TestCase``. If it's in our :mod:`repoze.bfg`
+from :mod:`unittest.TestCase`. If it's in our :mod:`repoze.bfg`
application, it will be found when ``setup.py test`` is run. It has
two test methods.
@@ -228,25 +233,29 @@ The first test method, ``test_view_fn_not_submitted`` tests the
``view_fn`` function in the case that no "form" values (represented by
request.params) have been submitted. Its first line registers a
"dummy template renderer" named ``templates/show.pt`` via the
-``testing_add_template`` method of a :term:`Configurator`; this method
-returns a ``DummyTemplateRenderer`` instance which we hang on to for
-later.
-
-We then create a ``DummyRequest`` object which simulates a WebOb
-request object using the ``repoze.bfg.testing.DummyRequest`` API. A
-``DummyRequest`` is a request object that requires less setup than a
-"real" :mod:`repoze.bfg` request. We call the function being tested
-with the manufactured request. When the function is called,
-``render_template_to_response`` will call the "dummy" template
-renderer object instead of the real template renderer object. When
-the dummy renderer is called, it will set attributes on itself
-corresponding to the non-path keyword arguments provided to the
-``render_template_to_response`` function. We check that the ``say``
-parameter sent into the template rendering function was ``Hello`` in
-this specific example. The ``assert_`` method of the renderer we've
-created will raise an ``AssertionError`` if the value passed to the
-renderer as ``say`` does not equal ``Hello`` (any number of keyword
-arguments are supported).
+:meth:`repoze.bfg.configuration.Configurator.testing_add_template`
+method; this method returns a
+:class:`repoze.bfg.testing.DummyTemplateRenderer` instance which we
+hang on to for later.
+
+We then create a :class:`repoze.bfg.testing.DummyRequest` object which
+simulates a WebOb request object API. A
+:class:`repoze.bfg.testing.DummyRequest` is a request object that
+requires less setup than a "real" :mod:`repoze.bfg` request. We call
+the function being tested with the manufactured request. When the
+function is called,
+:func:`repoze.bfg.chameleon_zpt.render_template_to_response` will call
+the "dummy" template renderer object instead of the real template
+renderer object. When the dummy renderer is called, it will set
+attributes on itself corresponding to the non-path keyword arguments
+provided to the
+:func:`repoze.bfg.chameleon_zpt.render_template_to_response` function.
+We check that the ``say`` parameter sent into the template rendering
+function was ``Hello`` in this specific example. The ``assert_``
+method of the renderer we've created will raise an
+:exc:`AssertionError` if the value passed to the renderer as ``say``
+does not equal ``Hello`` (any number of keyword arguments are
+supported).
The second test method, named ``test_view_fn_submitted`` tests the
alternate case, where the ``say`` form value has already been set in
@@ -255,12 +264,14 @@ assertion. We assert at the end of this that the renderer's ``say``
attribute is ``Yo``, as this is what is expected of the view function
in the branch it's testing.
-Note that the test calls the ``begin`` method of a
-:term:`Configurator` in its ``setUp`` method and the ``end`` method of
-the same in its ``tearDown`` method. If you use any of the
-``Configurator`` APIs during testing, be sure to use this pattern in
-your test setUp and tearDown; these methods make sure you're using a
-"fresh" :term:`application registry` per test run.
+Note that the test calls the
+:meth:`repoze.bfg.configuration.Configurator.begin` method in its
+``setUp`` method and the ``end`` method of the same in its
+``tearDown`` method. If you use any of the
+:class:`repoze.bfg.configuration.Configurator` APIs during testing, be
+sure to use this pattern in your test case's ``setUp`` and
+``tearDown``; these methods make sure you're using a "fresh"
+:term:`application registry` per test run.
See the :ref:`testing_module` chapter for the entire :mod:`repoze.bfg`
-specific testing API. This chapter describes APIs for registering a
@@ -337,9 +348,10 @@ environment.
str(len(body))))
Unless you cannot avoid it, you should prefer writing unit tests that
-use the :term:`Configurator` API to set up the right "mock"
-registrations rather than creating an integration test. Unit tests
-will run faster (because they do less for each test) and the result of
-a unit test is usually easier to make assertions about.
+use the :class:`repoze.bfg.configuration,Configurator` API to set up
+the right "mock" registrations rather than creating an integration
+test. Unit tests will run faster (because they do less for each test)
+and the result of a unit test is usually easier to make assertions
+about.