From fce5cb9e7d4ec5239fc65f3cad80805aaccf207c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 10 Dec 2009 03:28:25 +0000 Subject: Docs. --- docs/narr/models.rst | 10 +++---- docs/narr/project.rst | 2 +- docs/narr/unittesting.rst | 73 +++++++++++++++++++++++++++++++++++++++++++---- docs/narr/vhosting.rst | 2 +- 4 files changed, 74 insertions(+), 13 deletions(-) (limited to 'docs/narr') 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 +`_ 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 -- cgit v1.2.3