1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
.. _unittesting_chapter:
Unit Testing
============
The suggested mechanism for unit testing :mod:`repoze.bfg`
applications is the Python ``unittest`` module. :mod:`repoze.bfg`
provides a number of facilities that make unit tests easier to write.
The facilities become particularly useful when your code calls into
:mod:`repoze.bfg` -related framework functions.
Using the ``repoze.bfg.testing`` API
------------------------------------
The ``repoze.bfg.testing`` module provides a number of functions which
can be used during unit testing. For example, let's imagine you want
to unit test a :mod:`repoze.bfg` view function.
.. code-block:: python
:linenos:
def view_fn(context, request):
from repoze.bfg.chameleon_zpt import render_template_to_response
if 'say' in request.params:
return render_template_to_response('templates/submitted.pt',
say=request.params['say'])
return render_template_to_response('templates/show.pt', say='Hello')
Without invoking any ZCML or using the testing API, an attempt to run
this view function will result in an error. When a :mod:`repoze.bfg`
application starts normally, it will create an application registry
from the information it finds in the application's ``configure.zcml``
file. But if this application registry is not created and populated
(e.g. with ``bfg:view`` statements), 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
various application registry registrations for use under a unit
testing framework without needing to invoke the actual application
ZCML configuration. For example, if you wanted to test the above
``view_fn`` (assming it lived in ``my.package``), you could write a
unittest TestCase that used the testing API.
.. code-block:: python
:linenos:
import unittest
from zope.testing.cleanup import cleanUp
from repoze.bfg import testing
class MyTest(unittest.TestCase):
def setUp(self):
cleanUp()
def tearDown(self):
cleanUp()
def test_view_fn_not_submitted(self):
from my.package import view_fn
renderer = testing.registerDummyRenderer('templates/show.pt')
context = testing.DummyModel()
request = testing.DummyRequest()
response = view_fn(context, request)
self.assertEqual(renderer.say, 'Hello')
def test_view_fn_submitted(self):
from my.package import view_fn
renderer = testing.registerDummyRenderer('templates/submitted.pt')
context = testing.DummyModel()
request = testing.DummyRequest()
request.params['say'] = 'Yo'
response = view_fn(context, request)
self.assertEqual(renderer.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`
application, it will be found when ``setup.py test`` is run. It has
two test methods.
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
``registerDummyRenderer`` function (a ``repoze.bfg.testing`` API);
this function returns a DummyTemplateRenderer instance which we hang
on to for later. We then create a ``DummyRequest`` object (it
simulates a WebOb request object), and we create a ``DummyModel``
context object. We call the function being tested with the
manufactured context and 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 second test method, named ``test_view_fn_submitted`` tests the
alternate case, where the ``say`` form value has already been set in
the request and 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 ``zope.testing.cleanup.cleanUp`` function
in its ``setUp`` and ``tearDown`` functions. This is required to
perform cleanup between the test runs. If you use any of the testing
API, be sure to call this function at setup and teardown of individual
tests.
See the :ref:`testing_module` chapter for the entire :mod:`repoze.bfg`
-specific testing API. This chapter describes APIs for registering a
security policy, registering models at paths, registering event
listeners, registering views and view permissions, and classes
representing "dummy" implementations of a request and a model.
|