From a7e625785f65c41e5a6dc017b31bd0d74821474e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 31 May 2011 14:40:05 -0400 Subject: the canonical import location for HTTP exceptions/responses is now pyramid.response --- docs/narr/testing.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index bd45388c2..862eda9f0 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -191,11 +191,11 @@ function. :linenos: from pyramid.security import has_permission - from pyramid.exceptions import Forbidden + from pyramid.response import HTTPForbidden def view_fn(request): if not has_permission('edit', request.context, request): - raise Forbidden + raise HTTPForbidden return {'greeting':'hello'} Without doing anything special during a unit test, the call to @@ -207,7 +207,7 @@ application registry is not created and populated (e.g. by initializing the configurator with an authorization policy), like when you invoke application code via a unit test, :app:`Pyramid` API functions will tend to either fail or return default results. So how do you test the branch of the code in this -view function that raises :exc:`Forbidden`? +view function that raises :exc:`HTTPForbidden`? The testing API provided by :app:`Pyramid` allows you to simulate various application registry registrations for use under a unit testing framework @@ -230,16 +230,15 @@ without needing to invoke the actual application configuration implied by its testing.tearDown() def test_view_fn_forbidden(self): - from pyramid.exceptions import Forbidden + from pyramid.response import HTTPForbidden from my.package import view_fn self.config.testing_securitypolicy(userid='hank', permissive=False) request = testing.DummyRequest() request.context = testing.DummyResource() - self.assertRaises(Forbidden, view_fn, request) + self.assertRaises(HTTPForbidden, view_fn, request) def test_view_fn_allowed(self): - from pyramid.exceptions import Forbidden from my.package import view_fn self.config.testing_securitypolicy(userid='hank', permissive=True) @@ -265,7 +264,7 @@ We call the function being tested with the manufactured request. When the function is called, :func:`pyramid.security.has_permission` will call the "dummy" authentication policy we've registered through :meth:`~pyramid.config.Configuration.testing_securitypolicy`, which denies -access. We check that the view function raises a :exc:`Forbidden` error. +access. We check that the view function raises a :exc:`HTTPForbidden` error. The second test method, named ``test_view_fn_allowed`` tests the alternate case, where the authentication policy allows access. Notice that we pass -- cgit v1.2.3 From 99edc51a3b05309c7f5d98ff96289ec51b1d7660 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 11 Jun 2011 05:35:27 -0400 Subject: - Pyramid now expects Response objects to have a __call__ method which implements the WSGI application interface instead of the three webob attrs status, headerlist and app_iter. Backwards compatibility exists for code which returns response objects that do not have a __call__. - pyramid.response.Response is no longer an exception (and therefore cannot be raised in order to generate a response). - Changed my mind about moving stuff from pyramid.httpexceptions to pyramid.response. The stuff I moved over has been moved back to pyramid.httpexceptions. --- docs/narr/testing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 862eda9f0..05e851fde 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -191,7 +191,7 @@ function. :linenos: from pyramid.security import has_permission - from pyramid.response import HTTPForbidden + from pyramid.httpexceptions import HTTPForbidden def view_fn(request): if not has_permission('edit', request.context, request): @@ -230,7 +230,7 @@ without needing to invoke the actual application configuration implied by its testing.tearDown() def test_view_fn_forbidden(self): - from pyramid.response import HTTPForbidden + from pyramid.httpexceptions import HTTPForbidden from my.package import view_fn self.config.testing_securitypolicy(userid='hank', permissive=False) -- cgit v1.2.3 From d7ac00322fe7669d02d38b8f9fa02fa66e268fbc Mon Sep 17 00:00:00 2001 From: Cypha Date: Sun, 23 Oct 2011 04:12:12 -0400 Subject: updated Dive Into Python link --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 05e851fde..7ee432fa7 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -52,7 +52,7 @@ The suggested mechanism for unit and integration testing of a :app:`Pyramid` 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 `_ by Mark +Into Python `_ by Mark Pilgrim. :app:`Pyramid` provides a number of facilities that make unit, integration, -- cgit v1.2.3 From 3213d8e0a9f925ab2a6211b1134b087fc5adbad8 Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Fri, 24 Feb 2012 14:06:44 -0500 Subject: Trivial typos --- docs/narr/testing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 7ee432fa7..5ce2c8a66 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -303,12 +303,12 @@ In :app:`Pyramid`, a *unit test* typically relies on "mock" or "dummy" implementations to give the code under test only enough context to run. "Integration testing" implies another sort of testing. In the context of a -:app:`Pyramid`, integration test, the test logic tests the functionality of +:app:`Pyramid` integration test, the test logic tests the functionality of some code *and* its integration with the rest of the :app:`Pyramid` framework. In :app:`Pyramid` applications that are plugins to Pyramid, you can create an -integration test by including it's ``includeme`` function via +integration test by including its ``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 @@ -372,7 +372,7 @@ Creating Functional Tests Functional tests test your literal application. The below test assumes that your application's package name is ``myapp``, and -that there is view that returns an HTML body when the root URL is invoked. +that there is a view that returns an HTML body when the root URL is invoked. It further assumes that you've added a ``tests_require`` dependency on the ``WebTest`` package within your ``setup.py`` file. :term:`WebTest` is a functional testing package written by Ian Bicking. -- cgit v1.2.3 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/narr/testing.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'docs/narr/testing.rst') 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? ~~~~~ -- cgit v1.2.3 From eb72972b51f58037d1bc1c2e5d81ee10abd82afe Mon Sep 17 00:00:00 2001 From: Ronan Amicel Date: Thu, 30 Aug 2012 22:49:01 +0300 Subject: Fixed broken link in docs/narr/testing.rst Fixed link to "Dive into Python" (previous mirror is down). --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 5ce2c8a66..50e9d5604 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -52,7 +52,7 @@ The suggested mechanism for unit and integration testing of a :app:`Pyramid` 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 `_ by Mark +Into Python `_ by Mark Pilgrim. :app:`Pyramid` provides a number of facilities that make unit, integration, -- cgit v1.2.3 From ca402b50f2440b3ab7d7e0d9d058e72c20e9948b Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 27 Feb 2013 23:15:12 +0200 Subject: should be one word --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 20017064b..d5624469c 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -70,7 +70,7 @@ Test Set Up and Tear Down -------------------------- :app:`Pyramid` uses a "global" (actually :term:`thread local`) data structure -to hold on to two items: the current :term:`request` and the current +to hold onto two items: the current :term:`request` and the current :term:`application registry`. These data structures are available via the :func:`pyramid.threadlocal.get_current_request` and :func:`pyramid.threadlocal.get_current_registry` functions, respectively. -- cgit v1.2.3 From a85491f3cec005e9592c86bd78b66ec0d7a8e599 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Sun, 3 Mar 2013 15:41:37 -0500 Subject: No preposition needed at all. ;) --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index d5624469c..0801a8eae 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -70,7 +70,7 @@ Test Set Up and Tear Down -------------------------- :app:`Pyramid` uses a "global" (actually :term:`thread local`) data structure -to hold onto two items: the current :term:`request` and the current +to hold two items: the current :term:`request` and the current :term:`application registry`. These data structures are available via the :func:`pyramid.threadlocal.get_current_request` and :func:`pyramid.threadlocal.get_current_registry` functions, respectively. -- cgit v1.2.3 From d4683cbbfc370fd908592399a36ea47db2570b72 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 31 Mar 2013 00:29:12 +0200 Subject: fix some cross-references Also add webtest to intersphinx_mapping --- docs/narr/testing.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 0801a8eae..bfb1287d9 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -128,7 +128,7 @@ 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 +If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something other than ``None`` during the course of a single test, you can pass a :term:`request` object into the :func:`pyramid.testing.setUp` within the ``setUp`` method of your test: @@ -231,7 +231,7 @@ application registry is not created and populated (e.g. by initializing the configurator with an authorization policy), like when you invoke application code via a unit test, :app:`Pyramid` API functions will tend to either fail or return default results. So how do you test the branch of the code in this -view function that raises :exc:`HTTPForbidden`? +view function that raises :exc:`~pyramid.httpexceptions.HTTPForbidden`? The testing API provided by :app:`Pyramid` allows you to simulate various application registry registrations for use under a unit testing framework @@ -272,7 +272,7 @@ without needing to invoke the actual application configuration implied by its self.assertEqual(response, {'greeting':'hello'}) In the above example, we create a ``MyTest`` test case that inherits from -:mod:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will +:class:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will be found when ``setup.py test`` is run. It has two test methods. The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when @@ -287,8 +287,9 @@ request object that requires less setup than a "real" :app:`Pyramid` request. We call the function being tested with the manufactured request. When the function is called, :func:`pyramid.security.has_permission` will call the "dummy" authentication policy we've registered through -:meth:`~pyramid.config.Configuration.testing_securitypolicy`, which denies -access. We check that the view function raises a :exc:`HTTPForbidden` error. +:meth:`~pyramid.config.Configurator.testing_securitypolicy`, which denies +access. We check that the view function raises a +:exc:`~pyramid.httpexceptions.HTTPForbidden` error. The second test method, named ``test_view_fn_allowed`` tests the alternate case, where the authentication policy allows access. Notice that we pass @@ -425,4 +426,4 @@ invoke the root URL. We then assert that the returned HTML has the string ``Pyramid`` in it. See the :term:`WebTest` documentation for further information about the -methods available to a :class:`webtest.TestApp` instance. +methods available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From 7a0b5905d65c047ed3ac160f26f6566dfeba8f6a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 21 Apr 2013 23:07:50 +0300 Subject: remove ambiguity by indicating that the target is API documentation --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index bfb1287d9..9065488b6 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -125,7 +125,7 @@ method attached to ``MyTest`` will use an isolated registry. 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 +test. See the :ref:`testing_module` API for information about the extra arguments supported by these functions. If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something -- cgit v1.2.3 From 3fc77cfc0283315fe03497e79d07bbdaada6e006 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 21 Apr 2013 23:24:53 +0300 Subject: add a cross-ref... hyperlinks are nice --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index bfb1287d9..cc042fe39 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -202,7 +202,7 @@ any ``get_current*`` function. Using the ``Configurator`` and ``pyramid.testing`` APIs in Unit Tests --------------------------------------------------------------------- -The ``Configurator`` API and the ``pyramid.testing`` module provide a number +The ``Configurator`` API and the :mod:`pyramid.testing` module provide a number of functions which can be used during unit testing. These functions make :term:`configuration declaration` calls to the current :term:`application registry`, but typically register a "stub" or "dummy" feature in place of the -- cgit v1.2.3 From cdd8d40dac07d73bf60ebe5d9ddbb2d108d8666e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 00:47:36 +0300 Subject: add missing comma --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 56c62b996..0d0e292bf 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -291,7 +291,7 @@ function is called, :func:`pyramid.security.has_permission` will call the access. We check that the view function raises a :exc:`~pyramid.httpexceptions.HTTPForbidden` error. -The second test method, named ``test_view_fn_allowed`` tests the alternate +The second test method, named ``test_view_fn_allowed``, tests the alternate case, where the authentication policy allows access. Notice that we pass different values to :meth:`~pyramid.config.Configurator.testing_securitypolicy` to obtain this -- cgit v1.2.3 From 727508ba9a19955fb0f65e2dead3b578cee450c3 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 01:24:51 +0300 Subject: replace deprecated method --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 56c62b996..89ed038f2 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -373,7 +373,7 @@ after accessing some values that require a fully set up environment. result = my_view(request) self.assertEqual(result.status, '200 OK') body = result.app_iter[0] - self.failUnless('Welcome to' in body) + self.assertTrue('Welcome to' in body) self.assertEqual(len(result.headerlist), 2) self.assertEqual(result.headerlist[0], ('Content-Type', 'text/html; charset=UTF-8')) -- cgit v1.2.3 From 1bf894d55e6a536f31a8c4c2b99c29e96b3bd3a9 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 01:26:58 +0300 Subject: replace deprecated method --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 56c62b996..de5a04f56 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -416,7 +416,7 @@ functional testing package written by Ian Bicking. def test_root(self): res = self.testapp.get('/', status=200) - self.failUnless('Pyramid' in res.body) + self.assertTrue('Pyramid' in res.body) When this test is run, each test creates a "real" WSGI application using the ``main`` function in your ``myapp.__init__`` module and uses :term:`WebTest` -- cgit v1.2.3 From 613a7e5972ac15c0c296307de47944bfb07969c0 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 09:35:48 +0300 Subject: add a note about missing code --- docs/narr/testing.rst | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index ec5952a7c..88d6904c7 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -222,6 +222,12 @@ function. raise HTTPForbidden return {'greeting':'hello'} +.. note:: + + This code implies that you have defined a renderer imperatively in a + relevant :class:`pyramid.config.Configurator` instance, + otherwise it would fail when run normally. + Without doing anything special during a unit test, the call to :func:`~pyramid.security.has_permission` in this view function will always return a ``True`` value. When a :app:`Pyramid` application starts normally, -- cgit v1.2.3 From 3c2f95e8049bbd45b144d454daa68005361828b2 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Thu, 24 Oct 2013 23:52:42 +0100 Subject: Security APIs on pyramid.request.Request The pyramid.security Authorization API function has_permission is made available on the request. The pyramid.security Authentication API functions are now available as properties (unauthenticated_userid, authenticated_userid, effective_principals) and methods (remember_userid, forget_userid) on pyramid.request.Request. Backwards compatibility: For each of the APIs moved to request method or property, the original API in the pyramid.security module proxies to the request. Reworked tests to check module level b/c wrappers call through to mixins for each API. Tests that check no reg on request now do the right thing. Use a response callback to set the request headers for forget_userid and remember_userid. Update docs. Attempt to improve a documentation section referencing the pyramid.security.has_permission function in docs/narr/resources.rst Ensures backwards compatiblity for `pyramid.security.forget` and `pyramid.security.remember`. --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 88d6904c7..3f5d5ae6c 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -229,7 +229,7 @@ function. otherwise it would fail when run normally. Without doing anything special during a unit test, the call to -:func:`~pyramid.security.has_permission` in this view function will always +:meth:`~pyramid.request.Request.has_permission` in this view function will always return a ``True`` value. When a :app:`Pyramid` application starts normally, it will populate a :term:`application registry` using :term:`configuration declaration` calls made against a :term:`Configurator`. But if this -- cgit v1.2.3 From 3bd1fa5dd792d639615e5125b73caef8c65a0a30 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 30 Oct 2013 20:28:53 -0400 Subject: new api --- docs/narr/testing.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 3f5d5ae6c..5a5bf8fad 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -214,11 +214,10 @@ function. .. code-block:: python :linenos: - from pyramid.security import has_permission from pyramid.httpexceptions import HTTPForbidden def view_fn(request): - if not has_permission('edit', request.context, request): + if request.has_permission('edit'): raise HTTPForbidden return {'greeting':'hello'} @@ -229,15 +228,16 @@ function. otherwise it would fail when run normally. Without doing anything special during a unit test, the call to -:meth:`~pyramid.request.Request.has_permission` in this view function will always -return a ``True`` value. When a :app:`Pyramid` application starts normally, -it will populate a :term:`application registry` using :term:`configuration -declaration` calls made against a :term:`Configurator`. But if this -application registry is not created and populated (e.g. by initializing the -configurator with an authorization policy), like when you invoke application -code via a unit test, :app:`Pyramid` API functions will tend to either fail -or return default results. So how do you test the branch of the code in this -view function that raises :exc:`~pyramid.httpexceptions.HTTPForbidden`? +:meth:`~pyramid.request.Request.has_permission` in this view function will +always return a ``True`` value. When a :app:`Pyramid` application starts +normally, it will populate a :term:`application registry` using +:term:`configuration declaration` calls made against a :term:`Configurator`. +But if this application registry is not created and populated (e.g. by +initializing the configurator with an authorization policy), like when you +invoke application code via a unit test, :app:`Pyramid` API functions will tend +to either fail or return default results. So how do you test the branch of the +code in this view function that raises +:exc:`~pyramid.httpexceptions.HTTPForbidden`? The testing API provided by :app:`Pyramid` allows you to simulate various application registry registrations for use under a unit testing framework @@ -287,12 +287,12 @@ Its third line registers a "dummy" "non-permissive" authorization policy using the :meth:`~pyramid.config.Configurator.testing_securitypolicy` method, which is a special helper method for unit testing. -We then create a :class:`pyramid.testing.DummyRequest` object which simulates -a WebOb request object API. A :class:`pyramid.testing.DummyRequest` is a -request object that requires less setup than a "real" :app:`Pyramid` request. -We call the function being tested with the manufactured request. When the -function is called, :func:`pyramid.security.has_permission` will call the -"dummy" authentication policy we've registered through +We then create a :class:`pyramid.testing.DummyRequest` object which simulates a +WebOb request object API. A :class:`pyramid.testing.DummyRequest` is a request +object that requires less setup than a "real" :app:`Pyramid` request. We call +the function being tested with the manufactured request. When the function is +called, :meth:`pyramid.request.Request.has_permission` will call the "dummy" +authentication policy we've registered through :meth:`~pyramid.config.Configurator.testing_securitypolicy`, which denies access. We check that the view function raises a :exc:`~pyramid.httpexceptions.HTTPForbidden` error. -- cgit v1.2.3 From 2033eeb3602f330930585678aac926749b9c22f7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 10 Feb 2014 03:22:33 -0600 Subject: - Garden PR #1121 --- docs/narr/testing.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 5a5bf8fad..e001ad81c 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -319,8 +319,10 @@ registering resources at paths, registering event listeners, registering views and view permissions, and classes representing "dummy" implementations of a request and a resource. -See also the various methods of the :term:`Configurator` documented in -:ref:`configuration_module` that begin with the ``testing_`` prefix. +.. seealso:: + + See also the various methods of the :term:`Configurator` documented in + :ref:`configuration_module` that begin with the ``testing_`` prefix. .. index:: single: integration tests -- cgit v1.2.3 From 138706a24bd8e7051c60942c2789d8c16b4ca2ed Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 19 Nov 2014 23:06:17 +0000 Subject: Include code examples for integration and functional tests in docs #1001 Wrap lines as per convention. --- docs/narr/testing.rst | 142 +++++++++++++++++++++++--------------------------- 1 file changed, 66 insertions(+), 76 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index e001ad81c..3620f5e11 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -128,8 +128,9 @@ functions accepts various arguments that influence the environment of the test. See the :ref:`testing_module` API for information about the extra arguments supported by these functions. -If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something -other than ``None`` during the course of a single test, you can pass a +If you also want to make :func:`~pyramid.threadlocal.get_current_request` +return something other than ``None`` during the course of a single test, you +can pass a :term:`request` object into the :func:`pyramid.testing.setUp` within the ``setUp`` method of your test: @@ -333,66 +334,49 @@ Creating Integration Tests -------------------------- In :app:`Pyramid`, a *unit test* typically relies on "mock" or "dummy" -implementations to give the code under test only enough context to run. +implementations to give the code under test enough context to run. "Integration testing" implies another sort of testing. In the context of a -:app:`Pyramid` integration test, the test logic tests the functionality of -some code *and* its integration with the rest of the :app:`Pyramid` +:app:`Pyramid` integration test, the test logic exercises the functionality of +the code under test *and* its integration with the rest of the :app:`Pyramid` framework. -In :app:`Pyramid` applications that are plugins to Pyramid, you can create an -integration test by including its ``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`. +Creating an integration test for a :app:`Pyramid` application usually means +invoking the application's ``includeme`` function via +:meth:`pyramid.config.Configurator.include` within the test's setup code. This +causes the entire :app:`Pyramid` environment to be set up, simulating what +happens when your application is run "for real". This is a heavy-hammer way of +making sure that your tests have enough context to run properly, and 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 -there is a ``views`` module in the app with a function with the name -``my_view`` in it that returns the response 'Welcome to this application' -after accessing some values that require a fully set up environment. +.. seealso:: -.. code-block:: python - :linenos: + See more information about :app:`Pyramid`'s ``includme`` function. - import unittest +Let's demonstrate this by showing an integration test for a view. - from pyramid import testing +Given the following view definition, which assumes that your application's +:term:`package` name is ``myproject``, and within that :term:`package` there +exists a module ``views``, which in turn contains a :term:`view` function named +``my_view``: - class ViewIntegrationTests(unittest.TestCase): - def setUp(self): - """ This sets up the application registry with the - registrations your application declares in its ``includeme`` - function. - """ - import myapp - self.config = testing.setUp() - self.config.include('myapp') + .. literalinclude:: MyProject/myproject/views.py + :linenos: + :lines: 1-6 + :language: python - def tearDown(self): - """ Clear out the application registry """ - testing.tearDown() +You'd then create a ``tests`` module within your ``myproject`` package, +containing the following test code: - def test_my_view(self): - from myapp.views import my_view - request = testing.DummyRequest() - result = my_view(request) - self.assertEqual(result.status, '200 OK') - body = result.app_iter[0] - self.assertTrue('Welcome to' in body) - self.assertEqual(len(result.headerlist), 2) - self.assertEqual(result.headerlist[0], - ('Content-Type', 'text/html; charset=UTF-8')) - self.assertEqual(result.headerlist[1], ('Content-Length', - str(len(body)))) - -Unless you cannot avoid it, you should prefer writing unit tests that use the -:class:`~pyramid.config.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. + .. literalinclude:: MyProject/myproject/tests.py + :linenos: + :pyobject: ViewIntegrationTests + :language: python + +Writing unit tests that use the :class:`~pyramid.config.Configurator` API to +set up the right "mock" registrations is often preferred to creating +integration tests. Unit tests will run faster (because they do less for each +test) and are usually easier to reason about. .. index:: single: functional tests @@ -404,34 +388,40 @@ Creating Functional Tests Functional tests test your literal application. -The below test assumes that your application's package name is ``myapp``, and -that there is a view that returns an HTML body when the root URL is invoked. -It further assumes that you've added a ``tests_require`` dependency on the -``WebTest`` package within your ``setup.py`` file. :term:`WebTest` is a -functional testing package written by Ian Bicking. +In Pyramid, functional tests are typically written using the :term:`WebTest` +package, which provides APIs for invoking HTTP(S) requests to your application. -.. code-block:: python - :linenos: +Regardless of which testing :term:`package` you use, ensure to add a +``tests_require`` dependency on that package to to your application's +``setup.py`` file: - import unittest + .. literalinclude:: MyProject/setup.py + :linenos: + :emphasize-lines: 26-28,48 + :language: python - class FunctionalTests(unittest.TestCase): - def setUp(self): - from myapp import main - app = main({}) - from webtest import TestApp - self.testapp = TestApp(app) - - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertTrue('Pyramid' in res.body) - -When this test is run, each test creates a "real" WSGI application using the -``main`` function in your ``myapp.__init__`` module and uses :term:`WebTest` -to wrap that WSGI application. It assigns the result to ``self.testapp``. -In the test named ``test_root``, we use the testapp's ``get`` method to -invoke the root URL. We then assert that the returned HTML has the string -``Pyramid`` in it. +Assuming your :term:`package` is named ``myproject``, which contains a +``views`` module, which in turn contains a :term:`view` function ``my_view`` +that returns a HTML body when the root URL is invoked: + + .. literalinclude:: MyProject/myproject/views.py + :linenos: + :language: python + +Then the following example functional test (shown below) demonstrates invoking +the :term:`view` shown above: + + .. literalinclude:: MyProject/myproject/tests.py + :linenos: + :pyobject: FunctionalTests + :language: python + +When this test is run, each test method creates a "real" :term:`WSGI` +application using the ``main`` function in your ``myproject.__init__`` module, +using :term:`WebTest` to wrap that WSGI application. It assigns the result to +``self.testapp``. In the test named ``test_root``. The ``TestApp``'s ``get`` +method is used to invoke the root URL. Finally, an assertion is made that the +returned HTML contains the text ``MyProject``. See the :term:`WebTest` documentation for further information about the methods available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From 9c94e129f1bbb753317deba7ea5f790db13e0709 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Tue, 25 Nov 2014 20:59:18 +0000 Subject: Tweak seealso for the includeme function. --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 3620f5e11..ecda57489 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -351,7 +351,7 @@ code's integration with the rest of :app:`Pyramid`. .. seealso:: - See more information about :app:`Pyramid`'s ``includme`` function. + See also :ref:`including_configuration` Let's demonstrate this by showing an integration test for a view. -- cgit v1.2.3 From 4ade6de3bef51483a442fc404c350b3ce9c10988 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 22 Oct 2015 09:32:42 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes --- docs/narr/testing.rst | 195 ++++++++++++++++++++++++-------------------------- 1 file changed, 95 insertions(+), 100 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index ecda57489..c05ee41ad 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -13,34 +13,32 @@ application. In this context, a "unit" is often a function or a method of a class instance. The unit is also referred to as a "unit under test". The goal of a single unit test is to test **only** some permutation of the -"unit under test". If you write a unit test that aims to verify the result -of a particular codepath through a Python function, you need only be -concerned about testing the code that *lives in the function body itself*. -If the function accepts a parameter that represents a complex application -"domain object" (such as a resource, a database connection, or an SMTP -server), the argument provided to this function during a unit test *need not -be* and likely *should not be* a "real" implementation object. For example, -although a particular function implementation may accept an argument that -represents an SMTP server object, and the function may call a method of this -object when the system is operating normally that would result in an email -being sent, a unit test of this codepath of the function does *not* need to -test that an email is actually sent. It just needs to make sure that the -function calls the method of the object provided as an argument that *would* -send an email if the argument happened to be the "real" implementation of an -SMTP server object. +"unit under test". If you write a unit test that aims to verify the result of +a particular codepath through a Python function, you need only be concerned +about testing the code that *lives in the function body itself*. If the +function accepts a parameter that represents a complex application "domain +object" (such as a resource, a database connection, or an SMTP server), the +argument provided to this function during a unit test *need not be* and likely +*should not be* a "real" implementation object. For example, although a +particular function implementation may accept an argument that represents an +SMTP server object, and the function may call a method of this object when the +system is operating normally that would result in an email being sent, a unit +test of this codepath of the function does *not* need to test that an email is +actually sent. It just needs to make sure that the function calls the method +of the object provided as an argument that *would* send an email if the +argument happened to be the "real" implementation of an SMTP server object. An *integration test*, on the other hand, is a different form of testing in which the interaction between two or more "units" is explicitly tested. -Integration tests verify that the components of your application work -together. You *might* make sure that an email was actually sent in an -integration test. +Integration tests verify that the components of your application work together. +You *might* make sure that an email was actually sent in an integration test. A *functional test* is a form of integration test in which the application is -run "literally". You would *have to* make sure that an email was actually -sent in a functional test, because it tests your code end to end. +run "literally". You would *have to* make sure that an email was actually sent +in a functional test, because it tests your code end to end. -It is often considered best practice to write each type of tests for any -given codebase. Unit testing often provides the opportunity to obtain better +It is often considered best practice to write each type of tests for any given +codebase. Unit testing often provides the opportunity to obtain better "coverage": it's usually possible to supply a unit under test with arguments and/or an environment which causes *all* of its potential codepaths to be executed. This is usually not as easy to do with a set of integration or @@ -55,9 +53,9 @@ integration tests. A good :mod:`unittest` tutorial is available within `Dive Into Python `_ by Mark Pilgrim. -:app:`Pyramid` provides a number of facilities that make unit, integration, -and functional tests easier to write. The facilities become particularly -useful when your code calls into :app:`Pyramid` -related framework functions. +:app:`Pyramid` provides a number of facilities that make unit, integration, and +functional tests easier to write. The facilities become particularly useful +when your code calls into :app:`Pyramid`-related framework functions. .. index:: single: test setup @@ -67,42 +65,41 @@ useful when your code calls into :app:`Pyramid` -related framework functions. .. _test_setup_and_teardown: Test Set Up and Tear Down --------------------------- +------------------------- :app:`Pyramid` uses a "global" (actually :term:`thread local`) data structure to hold two items: the current :term:`request` and the current :term:`application registry`. These data structures are available via the :func:`pyramid.threadlocal.get_current_request` and -:func:`pyramid.threadlocal.get_current_registry` functions, respectively. -See :ref:`threadlocals_chapter` for information about these functions and the -data structures they return. +:func:`pyramid.threadlocal.get_current_registry` functions, respectively. 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 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 +: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. +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: +: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: @@ -117,22 +114,21 @@ of using this feature: def tearDown(self): testing.tearDown() -The above will make sure that -: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 above will make sure that :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 :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` API for information about the extra -arguments supported by these functions. +functions accept various arguments that influence the environment of the test. +See the :ref:`testing_module` API for information about the extra arguments +supported by these functions. If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something other than ``None`` during the course of a single test, you -can pass a -:term:`request` object into the :func:`pyramid.testing.setUp` within the -``setUp`` method of your test: +can pass a :term:`request` object into the :func:`pyramid.testing.setUp` within +the ``setUp`` method of your test: .. code-block:: python :linenos: @@ -148,24 +144,23 @@ can pass a def tearDown(self): 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 +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. +: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. 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. +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: @@ -193,8 +188,8 @@ they're used by frameworks. Sorry. So here's a rule of thumb: if you don't 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. +won't really hurt anything if the application you're testing does not call any +``get_current*`` function. .. index:: single: pyramid.testing @@ -225,15 +220,15 @@ function. .. note:: This code implies that you have defined a renderer imperatively in a - relevant :class:`pyramid.config.Configurator` instance, - otherwise it would fail when run normally. + relevant :class:`pyramid.config.Configurator` instance, otherwise it would + fail when run normally. Without doing anything special during a unit test, the call to :meth:`~pyramid.request.Request.has_permission` in this view function will always return a ``True`` value. When a :app:`Pyramid` application starts -normally, it will populate a :term:`application registry` using +normally, it will populate an :term:`application registry` using :term:`configuration declaration` calls made against a :term:`Configurator`. -But if this application registry is not created and populated (e.g. by +But if this application registry is not created and populated (e.g., by initializing the configurator with an authorization policy), like when you invoke application code via a unit test, :app:`Pyramid` API functions will tend to either fail or return default results. So how do you test the branch of the @@ -283,10 +278,10 @@ In the above example, we create a ``MyTest`` test case that inherits from be found when ``setup.py test`` is run. It has two test methods. The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when -the authentication policy forbids the current user the ``edit`` permission. -Its third line registers a "dummy" "non-permissive" authorization policy -using the :meth:`~pyramid.config.Configurator.testing_securitypolicy` method, -which is a special helper method for unit testing. +the authentication policy forbids the current user the ``edit`` permission. Its +third line registers a "dummy" "non-permissive" authorization policy using the +:meth:`~pyramid.config.Configurator.testing_securitypolicy` method, which is a +special helper method for unit testing. We then create a :class:`pyramid.testing.DummyRequest` object which simulates a WebOb request object API. A :class:`pyramid.testing.DummyRequest` is a request @@ -300,25 +295,25 @@ access. We check that the view function raises a The second test method, named ``test_view_fn_allowed``, tests the alternate case, where the authentication policy allows access. Notice that we pass -different values to -:meth:`~pyramid.config.Configurator.testing_securitypolicy` to obtain this -result. We assert at the end of this that the view function returns a value. +different values to :meth:`~pyramid.config.Configurator.testing_securitypolicy` +to obtain this result. We assert at the end of this that the view function +returns a value. 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. We assign the result of :func:`pyramid.testing.setUp` -as ``config`` on the unittest class. This is a :term:`Configurator` object -and all methods of the configurator can be called as necessary within -tests. 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 sure you're using a "fresh" -:term:`application registry` per test run. - -See the :ref:`testing_module` chapter for the entire :app:`Pyramid` -specific +``tearDown`` method. We assign the result of :func:`pyramid.testing.setUp` as +``config`` on the unittest class. This is a :term:`Configurator` object and +all methods of the configurator can be called as necessary within tests. 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 sure you're using a "fresh" :term:`application registry` per test +run. + +See the :ref:`testing_module` chapter for the entire :app:`Pyramid`-specific testing API. This chapter describes APIs for registering a security policy, -registering resources at paths, registering event listeners, registering -views and view permissions, and classes representing "dummy" implementations -of a request and a resource. +registering resources at paths, registering event listeners, registering views +and view permissions, and classes representing "dummy" implementations of a +request and a resource. .. seealso:: @@ -392,7 +387,7 @@ In Pyramid, functional tests are typically written using the :term:`WebTest` package, which provides APIs for invoking HTTP(S) requests to your application. Regardless of which testing :term:`package` you use, ensure to add a -``tests_require`` dependency on that package to to your application's +``tests_require`` dependency on that package to your application's ``setup.py`` file: .. literalinclude:: MyProject/setup.py @@ -400,7 +395,7 @@ Regardless of which testing :term:`package` you use, ensure to add a :emphasize-lines: 26-28,48 :language: python -Assuming your :term:`package` is named ``myproject``, which contains a +Let us assume your :term:`package` is named ``myproject`` which contains a ``views`` module, which in turn contains a :term:`view` function ``my_view`` that returns a HTML body when the root URL is invoked: @@ -408,8 +403,8 @@ that returns a HTML body when the root URL is invoked: :linenos: :language: python -Then the following example functional test (shown below) demonstrates invoking -the :term:`view` shown above: +Then the following example functional test demonstrates invoking the above +:term:`view`: .. literalinclude:: MyProject/myproject/tests.py :linenos: @@ -419,9 +414,9 @@ the :term:`view` shown above: When this test is run, each test method creates a "real" :term:`WSGI` application using the ``main`` function in your ``myproject.__init__`` module, using :term:`WebTest` to wrap that WSGI application. It assigns the result to -``self.testapp``. In the test named ``test_root``. The ``TestApp``'s ``get`` +``self.testapp``. In the test named ``test_root``. The ``TestApp``'s ``GET`` method is used to invoke the root URL. Finally, an assertion is made that the returned HTML contains the text ``MyProject``. -See the :term:`WebTest` documentation for further information about the -methods available to a :class:`webtest.app.TestApp` instance. +See the :term:`WebTest` documentation for further information about the methods +available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From 312aa1b996f786dc18d8189a7a6d9813ad609645 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 14 Dec 2015 02:26:32 -0800 Subject: - Remove broken integration test example from testing and source file, per #2172 - Update functional test with explicit instructions and to sync with actual starter scaffold --- docs/narr/testing.rst | 73 +++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 31 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index c05ee41ad..a3f62058b 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -348,26 +348,6 @@ code's integration with the rest of :app:`Pyramid`. See also :ref:`including_configuration` -Let's demonstrate this by showing an integration test for a view. - -Given the following view definition, which assumes that your application's -:term:`package` name is ``myproject``, and within that :term:`package` there -exists a module ``views``, which in turn contains a :term:`view` function named -``my_view``: - - .. literalinclude:: MyProject/myproject/views.py - :linenos: - :lines: 1-6 - :language: python - -You'd then create a ``tests`` module within your ``myproject`` package, -containing the following test code: - - .. literalinclude:: MyProject/myproject/tests.py - :linenos: - :pyobject: ViewIntegrationTests - :language: python - Writing unit tests that use the :class:`~pyramid.config.Configurator` API to set up the right "mock" registrations is often preferred to creating integration tests. Unit tests will run faster (because they do less for each @@ -388,22 +368,53 @@ package, which provides APIs for invoking HTTP(S) requests to your application. Regardless of which testing :term:`package` you use, ensure to add a ``tests_require`` dependency on that package to your application's -``setup.py`` file: +``setup.py`` file. Using the project ``MyProject`` generated by the starter +scaffold as described in :doc:`project`, we would insert the following code immediately following the +``requires`` block in the file ``MyProject/setup.py``. - .. literalinclude:: MyProject/setup.py - :linenos: - :emphasize-lines: 26-28,48 - :language: python +.. code-block:: ini + :linenos: + :lineno-start: 11 + :emphasize-lines: 8- + + requires = [ + 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'waitress', + ] + + test_requires = [ + 'webtest', + ] + +Remember to change the dependency. + +.. code-block:: ini + :linenos: + :lineno-start: 39 + :emphasize-lines: 2 + + install_requires=requires, + tests_require=test_requires, + test_suite="myproject", + +As always, whenever you change your dependencies, make sure to run the +following command. + +.. code-block:: bash + + $VENV/bin/python setup.py develop -Let us assume your :term:`package` is named ``myproject`` which contains a -``views`` module, which in turn contains a :term:`view` function ``my_view`` -that returns a HTML body when the root URL is invoked: +In your ``MyPackage`` project, your :term:`package` is named ``myproject`` +which contains a ``views`` module, which in turn contains a :term:`view` +function ``my_view`` that returns an HTML body when the root URL is invoked: .. literalinclude:: MyProject/myproject/views.py :linenos: :language: python -Then the following example functional test demonstrates invoking the above +The following example functional test demonstrates invoking the above :term:`view`: .. literalinclude:: MyProject/myproject/tests.py @@ -414,9 +425,9 @@ Then the following example functional test demonstrates invoking the above When this test is run, each test method creates a "real" :term:`WSGI` application using the ``main`` function in your ``myproject.__init__`` module, using :term:`WebTest` to wrap that WSGI application. It assigns the result to -``self.testapp``. In the test named ``test_root``. The ``TestApp``'s ``GET`` +``self.testapp``. In the test named ``test_root``, the ``TestApp``'s ``GET`` method is used to invoke the root URL. Finally, an assertion is made that the -returned HTML contains the text ``MyProject``. +returned HTML contains the text ``Pyramid``. See the :term:`WebTest` documentation for further information about the methods available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From e976a625c7eadd41cdafae21bb8cf74b264ddc41 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 12 Apr 2016 05:10:40 -0700 Subject: update testing.rst - replace nose with py.test - use pip - use literalinclude of MyProject/setup.py instead of copy-pasta --- docs/narr/testing.rst | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) (limited to 'docs/narr/testing.rst') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index a3f62058b..354a462d4 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -275,7 +275,7 @@ without needing to invoke the actual application configuration implied by its In the above example, we create a ``MyTest`` test case that inherits from :class:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will -be found when ``setup.py test`` is run. It has two test methods. +be found when ``py.test`` is run. It has two test methods. The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when the authentication policy forbids the current user the ``edit`` permission. Its @@ -365,46 +365,37 @@ Functional tests test your literal application. In Pyramid, functional tests are typically written using the :term:`WebTest` package, which provides APIs for invoking HTTP(S) requests to your application. +We also like ``py.test`` and ``pytest-cov`` to provide simple testing and +coverage reports. -Regardless of which testing :term:`package` you use, ensure to add a -``tests_require`` dependency on that package to your application's -``setup.py`` file. Using the project ``MyProject`` generated by the starter -scaffold as described in :doc:`project`, we would insert the following code immediately following the -``requires`` block in the file ``MyProject/setup.py``. +Regardless of which testing :term:`package` you use, be sure to add a +``tests_require`` dependency on that package to your application's ``setup.py`` +file. Using the project ``MyProject`` generated by the starter scaffold as +described in :doc:`project`, we would insert the following code immediately +following the ``requires`` block in the file ``MyProject/setup.py``. -.. code-block:: ini +.. literalinclude:: MyProject/setup.py + :language: python :linenos: + :lines: 11-22 :lineno-start: 11 :emphasize-lines: 8- - requires = [ - 'pyramid', - 'pyramid_chameleon', - 'pyramid_debugtoolbar', - 'waitress', - ] - - test_requires = [ - 'webtest', - ] - Remember to change the dependency. -.. code-block:: ini +.. literalinclude:: MyProject/setup.py + :language: python :linenos: - :lineno-start: 39 - :emphasize-lines: 2 - - install_requires=requires, - tests_require=test_requires, - test_suite="myproject", + :lines: 40-44 + :lineno-start: 40 + :emphasize-lines: 2-4 -As always, whenever you change your dependencies, make sure to run the -following command. +As always, whenever you change your dependencies, make sure to run the correct +``pip install -e`` command. .. code-block:: bash - $VENV/bin/python setup.py develop + $VENV/bin/pip install -e ".[testing]" In your ``MyPackage`` project, your :term:`package` is named ``myproject`` which contains a ``views`` module, which in turn contains a :term:`view` -- cgit v1.2.3