summaryrefslogtreecommitdiff
path: root/docs/narr
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-12-10 03:28:25 +0000
committerChris McDonough <chrism@agendaless.com>2009-12-10 03:28:25 +0000
commitfce5cb9e7d4ec5239fc65f3cad80805aaccf207c (patch)
tree917f3f33b7f4171b0528fd01d7fc53c315024110 /docs/narr
parent16cdd27071ef91a56150f1d47d1a51a141f6c55f (diff)
downloadpyramid-fce5cb9e7d4ec5239fc65f3cad80805aaccf207c.tar.gz
pyramid-fce5cb9e7d4ec5239fc65f3cad80805aaccf207c.tar.bz2
pyramid-fce5cb9e7d4ec5239fc65f3cad80805aaccf207c.zip
Docs.
Diffstat (limited to 'docs/narr')
-rw-r--r--docs/narr/models.rst10
-rw-r--r--docs/narr/project.rst2
-rw-r--r--docs/narr/unittesting.rst73
-rw-r--r--docs/narr/vhosting.rst2
4 files changed, 74 insertions, 13 deletions
diff --git a/docs/narr/models.rst b/docs/narr/models.rst
index 535aa6ac3..e1d2fd635 100644
--- a/docs/narr/models.rst
+++ b/docs/narr/models.rst
@@ -191,9 +191,9 @@ In order for :mod:`repoze.bfg` location, security, URL-generation, and
traversal functions (such as the functions exposed in
:ref:`location_module`, :ref:`traversal_module`, and :ref:`url_module`
as well as certain functions in :ref:`security_module` ) to work
-properly against a instances in a model graph, all nodes in the graph
-must be "location-aware". This means they must have two attributes:
-``__parent__`` and ``__name__``.
+properly against a instances in an object graph, all nodes in the
+graph must be "location-aware". This means they must have two
+attributes: ``__parent__`` and ``__name__``.
The ``__parent__`` attribute should be a reference to the node's
parent model instance in the graph. The ``__name__`` attribute should
@@ -238,10 +238,10 @@ more information about how a model instance becomes the context.
The APIs provided by :ref:`traversal_module` are used against model
instances. These functions can be used to find the "path" of a model,
-find the URL of a model, the root model in a model graph, and so on.
+find the URL of a model, the root model in an object graph, and so on.
The APIs provided by :ref:`location_module` are used against model
-instances. These can be used to walk down a model graph, or
+instances. These can be used to walk down an object graph, or
conveniently locate one object "inside" another.
Some APIs in :ref:`security_module` accept a model object as a
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index 18e63b474..81e570e36 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -697,7 +697,7 @@ behavior.
#. Line 6 is a "root factory" function that will be called by the
:mod:`repoze.bfg` *Router* for each request when it wants to find
- the root of the model graph. Conventionally this is called
+ the root of the object graph. Conventionally this is called
``get_root``.
In a "real" application, the root object would not be such a simple
diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst
index 2af2b7558..cc8ab6e32 100644
--- a/docs/narr/unittesting.rst
+++ b/docs/narr/unittesting.rst
@@ -3,11 +3,53 @@
Unit and Integration 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.
+*Unit testing* is the act of testing a "unit" in your 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 a a model, 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.
+
+It is often considered best practice to write both types 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 tests, but integration testing provides a
+measure of assurance that your "units" work together, as they will be
+expected to when your application is run in production.
+
+The suggested mechanism for unit and integration testing of a
+:mod:`repoze.bfg` application is the Python ``unittest`` module.
+Although this module is named ``unittest``, it is actually capable of
+driving both unit and integration tests. A good ``unittest`` tutorial
+is available within `Dive Into Python
+<http://diveintopython.org/unit_testing/index.html>`_ by Mark Pilgrim.
+
+:mod:`repoze.bfg` provides a number of facilities that make unit and
+integration tests easier to write. The facilities become particularly
+useful when your code calls into :mod:`repoze.bfg` -related framework
+functions.
.. _test_setup_and_teardown:
@@ -19,7 +61,8 @@ structure to hold on to two items: the current :term:`request` and the
current :term:`application registry`. These data structures are
available via the ``repoze.bfg.threadlocal.get_current_request`` and
``repoze.bfg.threadlocal.get_current_registry`` functions,
-respectively.
+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
:mod:`repoze.bfg` code which uses the ``get_current_*`` functions, you
@@ -27,6 +70,24 @@ will need to use the ``repoze.bfg.testing.setUp`` and
``repoze.bfg.testing.tearDown`` functions within the ``setUp`` and
``tearDown`` methods of your unit tests, respectively.
+The ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``
+functions allow you to supply a unit test with an environment that has
+a default registry and a default request for the duration of a single
+test. Here's an example of using both:
+
+.. code-block:: python
+ :linenos:
+
+ import unittest
+ from repoze.bfg import testing
+
+ class MyTest(unittest.TestCase):
+ def setUp(self):
+ testing.setUp()
+
+ def tearDown(self):
+ testing.tearDown()
+
If you don't *know* whether you're calling code that uses these
functions, a rule of thumb applies: just always use the
``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``
diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst
index 7394f2173..ee2d2be4b 100644
--- a/docs/narr/vhosting.rst
+++ b/docs/narr/vhosting.rst
@@ -70,7 +70,7 @@ Virtual Root Support
applications. These are explained below.
Virtual root support is useful when you'd like to host some model in a
-:mod:`repoze.bfg` model graph as an application under a URL pathname
+:mod:`repoze.bfg` object graph as an application under a URL pathname
that does not include the model path itself. For example, you might
want to serve the object at the traversal path ``/cms`` as an
application reachable via ``http://example.com/`` (as opposed to