From fbbb20c7953370c86f999e865b1a9d682690eb70 Mon Sep 17 00:00:00 2001 From: Brian Sutherland Date: Sat, 16 Jun 2012 12:57:46 +0200 Subject: A context manager for test setup --- docs/api/testing.rst | 2 ++ docs/narr/testing.rst | 24 +++++++++++++++++++ pyramid/testing.py | 35 +++++++++++++++++++++++++++ pyramid/tests/test_testing.py | 55 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+) diff --git a/docs/api/testing.rst b/docs/api/testing.rst index f388dc263..1366a1795 100644 --- a/docs/api/testing.rst +++ b/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 diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 5ce2c8a66..89bc1a089 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -157,6 +157,30 @@ 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. +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? ~~~~~ diff --git a/pyramid/testing.py b/pyramid/testing.py index 40e90cda6..5589f6ae2 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -1,5 +1,6 @@ import copy import os +from contextlib import contextmanager from zope.deprecation import deprecated @@ -941,3 +942,37 @@ def skip_on(*platforms): # pragma: no cover 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) diff --git a/pyramid/tests/test_testing.py b/pyramid/tests/test_testing.py index 5b0073b81..779c66818 100644 --- a/pyramid/tests/test_testing.py +++ b/pyramid/tests/test_testing.py @@ -932,3 +932,58 @@ class DummyRendererInfo(object): 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) -- cgit v1.2.3 From d6f0fd56fb93d30d8d7d6b490a57967d940b0135 Mon Sep 17 00:00:00 2001 From: Brian Sutherland Date: Sat, 16 Jun 2012 12:58:58 +0200 Subject: add myself to contributers --- CONTRIBUTORS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 027fc0857..65ff1b2f2 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -174,3 +174,5 @@ Contributors - Marin Rukavina, 2012/05/03 - Marc Abramowitz, 2012/06/13 + +- Brian Sutherland, 2012/06/16 -- cgit v1.2.3