summaryrefslogtreecommitdiff
path: root/docs/narr/testing.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/narr/testing.rst')
-rw-r--r--docs/narr/testing.rst154
1 files changed, 76 insertions, 78 deletions
diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst
index 007b96c2a..0968ad229 100644
--- a/docs/narr/testing.rst
+++ b/docs/narr/testing.rst
@@ -78,81 +78,84 @@ See :ref:`threadlocals_chapter` for information about these functions and the
data structures they return.
If your code uses these ``get_current_*`` functions or calls :app:`Pyramid`
-code which uses ``get_current_*`` functions, you will need to construct a
-:term:`Configurator` and call its ``begin`` method within the ``setUp``
-method of your unit test and call the same Configurator's ``end`` method
-within the ``tearDown`` method of your unit test.
-
-We'll also instruct the Configurator we use during testing to *autocommit*.
-Normally when a Configurator is used by an application, it defers performing
-any "real work" until its ``.commit`` method is called (often implicitly by
-the :meth:`pyramid.config.Configurator.make_wsgi_app` method). Passing
-``autocommit=True`` to the Configurator constructor causes the Configurator
-to perform all actions implied by methods called on it immediately, which is
-more convenient for unit-testing purposes than needing to call
-:meth:`pyramid.config.Configurator.commit` in each test.
-
-The use of a Configurator and its ``begin`` and ``end`` methods allows you to
-supply each unit test method in a test case with an environment that has an
-isolated registry and an isolated request for the duration of a single test.
-Here's an example of using this feature:
+code which uses ``get_current_*`` functions, you will need to call
+:func:`pyramid.testing.setUp` in your test setup and you will need to call
+:func:`pyramid.testing.tearDown` in your test teardown.
+:func:`~pyramid.testing.setUp` pushes a registry onto the :term:`thread
+local` stack, which makes the ``get_current_*`` functions work. It returns a
+:term:`Configurator` object which can be used to perform extra configuration
+required by the code under test. :func:`~pyramid.testing.tearDown` pops the
+thread local stack.
+
+Normally when a Configurator is used directly with the ``main`` block of
+a Pyramid application, it defers performing any "real work" until its
+``.commit`` method is called (often implicitly by the
+:meth:`pyramid.config.Configurator.make_wsgi_app` method). The
+Configurator returned by :func:`~pyramid.testing.setUp` is an
+*autocommitting* Configurator, however, which performs all actions
+implied by methods called on it immediately. This is more convenient
+for unit-testing purposes than needing to call
+:meth:`pyramid.config.Configurator.commit` in each test after adding
+extra configuration statements.
+
+The use of the :func:`~pyramid.testing.setUp` and
+:func:`~pyramid.testing.tearDown` functions allows you to supply each unit
+test method in a test case with an environment that has an isolated registry
+and an isolated request for the duration of a single test. Here's an example
+of using this feature:
.. code-block:: python
:linenos:
import unittest
- from pyramid.config import Configurator
+ from pyramid import testing
class MyTest(unittest.TestCase):
def setUp(self):
- self.config = Configurator(autocommit=True)
- self.config.begin()
+ self.config = testing.setUp()
def tearDown(self):
- self.config.end()
+ testing.tearDown()
The above will make sure that
-:func:`pyramid.threadlocal.get_current_registry` will return the
-:term:`application registry` associated with the ``config`` Configurator
-instance when :func:`pyramid.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.
+:func:`pyramid.threadlocal.get_current_registry` called within a test
+case method of ``MyTest`` will return the :term:`application registry`
+associated with the ``config`` Configurator instance. Each test case
+method attached to ``MyTest`` will use an isolated registry.
-The :meth:`pyramid.config.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.
+The :func:`~pyramid.testing.setUp` and :func:`~pyramid.testing.tearDown`
+functions accepts various arguments that influence the environment of the
+test. See the :ref:`testing_module` chapter for information about the extra
+arguments supported by these functions.
If you also want to make :func:`pyramid.get_current_request` return something
other than ``None`` during the course of a single test, you can pass a
-:term:`request` object into the :meth:`pyramid.config.Configurator.begin`
-method of the Configurator within the ``setUp`` method of your test:
+:term:`request` object into the :func:`pyramid.testing.setUp` within the
+``setUp`` method of your test:
.. code-block:: python
:linenos:
import unittest
- from pyramid.config import Configurator
from pyramid import testing
class MyTest(unittest.TestCase):
def setUp(self):
- self.config = Configurator(autocommit=True)
request = testing.DummyRequest()
- self.config.begin(request=request)
+ self.config = testing.setUp(request=request)
def tearDown(self):
- self.config.end()
-
-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
-:func:`pyramid.threadlocal.get_current_request` will receive the request you
-passed into the ``begin`` method. Otherwise, during testing,
-:func:`pyramid.threadlocal.get_current_request` will return ``None``. We use
-a "dummy" request implementation supplied by
-:class:`pyramid.testing.DummyRequest` because it's easier to construct than a
-"real" :app:`Pyramid` request object.
+ testing.tearDown()
+
+If you pass a :term:`request` object into :func:`pyramid.testing.setUp`
+within your test case's ``setUp``, any test method attached to the
+``MyTest`` test case that directly or indirectly calls
+:func:`pyramid.threadlocal.get_current_request` will receive the request
+object. Otherwise, during testing,
+:func:`pyramid.threadlocal.get_current_request` will return ``None``.
+We use a "dummy" request implementation supplied by
+:class:`pyramid.testing.DummyRequest` because it's easier to construct
+than a "real" :app:`Pyramid` request object.
What?
~~~~~
@@ -162,18 +165,18 @@ they're used by frameworks. Sorry. So here's a rule of thumb: if you don't
*know* whether you're calling code that uses the
:func:`pyramid.threadlocal.get_current_registry` or
:func:`pyramid.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
-an autocommitting 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 ``get_current*`` function.
+about any of this, but you still want to write test code, just always call
+:func:`pyramid.testing.setUp` in your test's ``setUp`` method and
+:func:`pyramid.testing.tearDown` in your tests' ``tearDown`` method. This
+won't really hurt anything if the application you're testing does not call
+any ``get_current*`` function.
.. index::
single: pyramid.testing
single: Configurator testing API
Using the ``Configurator`` and ``pyramid.testing`` APIs in Unit Tests
-------------------------------------------------------------------------
+---------------------------------------------------------------------
The ``Configurator`` API and the ``pyramid.testing`` module provide a number
of functions which can be used during unit testing. These functions make
@@ -198,13 +201,11 @@ Without invoking any startup code or using the testing API, an attempt to run
this view function in a unit test will result in an error. When a
:app:`Pyramid` application starts normally, it will populate 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
+made against a :term:`Configurator`. But if this application registry is not
+created and populated (e.g. with an
:meth:`pyramid.config.Configurator.add_view` :term:`configuration
-declaration` or ``view`` declarations in :term:`ZCML`), like when you invoke
-application code via a unit test, :app:`Pyramid` API functions will tend to
-fail.
+declaration`), like when you invoke application code via a unit test,
+:app:`Pyramid` API functions will tend to fail.
The testing API provided by :app:`Pyramid` allows you to simulate various
application registry registrations for use under a unit testing framework
@@ -217,16 +218,14 @@ without needing to invoke the actual application configuration implied by its
:linenos:
import unittest
- from pyramid.config import Configurator
from pyramid import testing
class MyTest(unittest.TestCase):
def setUp(self):
- self.config = Configurator(autocommit=True)
- self.config.begin()
+ self.config = testing.setUp()
def tearDown(self):
- self.config.end()
+ testing.tearDown()
def test_view_fn_not_submitted(self):
from my.package import view_fn
@@ -277,8 +276,8 @@ performs a similar template registration and 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 :meth:`pyramid.config.Configurator.begin` method
-in its ``setUp`` method and the ``end`` method of the same in its
+Note that the test calls the :func:`pyramid.testing.setUp` function in its
+``setUp`` method and the :func:`pyramid.testing.tearDown` function in its
``tearDown`` method. If you use any of the
:class:`pyramid.config.Configurator` APIs during testing, be sure to use this
pattern in your test case's ``setUp`` and ``tearDown``; these methods make
@@ -309,12 +308,13 @@ implementations to give the code under test only enough context to run.
some code *and* its integration with the rest of the :app:`Pyramid`
framework.
-In :app:`Pyramid` applications that use :term:`ZCML`, you can create an
-integration test by *loading its ZCML* in the test's setup code. This causes
-the entire :app:`Pyramid` environment to be set up and torn down as if your
-application was running "for real". This is a heavy-hammer way of making
-sure that your tests have enough context to run properly, and it tests your
-code's integration with the rest of :app:`Pyramid`.
+In :app:`Pyramid` applications that are plugins to Pyramid, you can create an
+integration test by including it's ``includeme`` function via
+:meth:`pyramid.config.Configurator.include` in the test's setup code. This
+causes the entire :app:`Pyramid` environment to be set up and torn down as if
+your application was running "for real". This is a heavy-hammer way of
+making sure that your tests have enough context to run properly, and it tests
+your code's integration with the rest of :app:`Pyramid`.
Let's demonstrate this by showing an integration test for a view. The below
test assumes that your application's package name is ``myapp``, and that
@@ -327,23 +327,21 @@ after accessing some values that require a fully set up environment.
import unittest
- from pyramid.config import Configurator
from pyramid import testing
class ViewIntegrationTests(unittest.TestCase):
def setUp(self):
""" This sets up the application registry with the
- registrations your application declares in its configure.zcml
- (including dependent registrations for pyramid itself).
+ registrations your application declares in its ``includeme``
+ function.
"""
import myapp
- self.config = Configurator(package=myapp, autocommit=True)
- self.config.begin()
- self.config.load_zcml('myapp:configure.zcml')
+ self.config = testing.setUp()
+ self.config.include('myapp')
def tearDown(self):
""" Clear out the application registry """
- self.config.end()
+ testing.tearDown()
def test_my_view(self):
from myapp.views import my_view