Brian Sutherland
2012-06-16 fbbb20c7953370c86f999e865b1a9d682690eb70
A context manager for test setup
4 files modified
116 ■■■■■ changed files
docs/api/testing.rst 2 ●●●●● patch | view | raw | blame | history
docs/narr/testing.rst 24 ●●●●● patch | view | raw | blame | history
pyramid/testing.py 35 ●●●●● patch | view | raw | blame | history
pyramid/tests/test_testing.py 55 ●●●●● patch | view | raw | blame | history
docs/api/testing.rst
@@ -9,6 +9,8 @@
  .. autofunction:: tearDown
  .. autofunction:: testConfig(registry=None, request=None, hook_zca=True, autocommit=True, settings=None)
  .. autofunction:: cleanUp
  .. autoclass:: DummyResource
docs/narr/testing.rst
@@ -157,6 +157,30 @@
:class:`pyramid.testing.DummyRequest` because it's easier to construct
than a "real" :app:`Pyramid` request object.
Test setup using a context manager
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An alternative style of setting up a test configuration is to use the
`with` statement and :func:`pyramid.testing.testConfig` to create a
context manager. The context manager will call
:func:`pyramid.testing.setUp` before the code under test and
:func:`pyramid.testing.tearDown` afterwards.
This style is useful for small self-contained tests. For example:
.. code-block:: python
   :linenos:
   import unittest
   class MyTest(unittest.TestCase):
       def test_my_function(self):
           from pyramid import testing
           with testing.testConfig() as config:
               config.add_route('bar', '/bar/{id}')
               my_function_which_needs_route_bar()
What?
~~~~~
pyramid/testing.py
@@ -1,5 +1,6 @@
import copy
import os
from contextlib import contextmanager
from zope.deprecation import deprecated
@@ -941,3 +942,37 @@
            return wrapper
    return decorator
skip_on.os_name = os.name # for testing
@contextmanager
def testConfig(registry=None,
        request=None,
        hook_zca=True,
        autocommit=True,
        settings=None):
    """Returns a context manager for test set up.
    This context manager calls :func:`pyramid.testing.testSetup` when
    entering and :func:`pyramid.testing.tearDown` when exiting.
    All arguments are passed directly to :func:`pyramid.testing.testSetup`.
    If the ZCA is hooked, it will always be un-hooked in tearDown.
    This context manager allows you to write test code like this:
    .. code-block:: python
        :linenos:
        with testConfig() as config:
            config.add_route('bar', '/bar/{id}')
            req = DummyRequest()
            resp = myview(req),
    """
    config = setUp(registry=registry,
            request=request,
            hook_zca=hook_zca,
            autocommit=autocommit,
            settings=settings)
    try:
        yield config
    finally:
        tearDown(unhook_zca=hook_zca)
pyramid/tests/test_testing.py
@@ -932,3 +932,58 @@
    def __init__(self, kw):
        self.__dict__.update(kw)
        
class Test_testConfig(unittest.TestCase):
    def _setUp(self, **kw):
        self._log.append(('setUp', kw))
        return 'fake config'
    def _tearDown(self, **kw):
        self._log.append(('tearDown', kw))
    def setUp(self):
        from pyramid import testing
        self._log = []
        self._orig_setUp = testing.setUp
        testing.setUp = self._setUp
        self._orig_tearDown = testing.tearDown
        testing.tearDown = self._tearDown
    def tearDown(self):
        from pyramid import testing
        testing.setUp = self._orig_setUp
        testing.tearDown = self._orig_tearDown
    def _callFUT(self, inner, **kw):
        from pyramid.testing import testConfig
        with testConfig(**kw) as config:
            inner(config)
    def test_ok_calls(self):
        self.assertEqual(self._log, [])
        def inner(config):
            self.assertEqual(self._log,
                    [('setUp',
                        {'autocommit': True,
                            'hook_zca': True,
                            'registry': None,
                            'request': None,
                            'settings': None})])
            self._log.pop()
        self._callFUT(inner)
        self.assertEqual(self._log,
                [('tearDown', {'unhook_zca': True})])
    def test_teardown_called_on_exception(self):
        class TestException(Exception):
            pass
        def inner(config):
            self._log = []
            raise TestException('oops')
        self.assertRaises(TestException, self._callFUT, inner)
        self.assertEqual(self._log[0][0], 'tearDown')
    def test_ok_get_config(self):
        def inner(config):
            self.assertEqual(config, 'fake config')
        self._callFUT(inner)