discover: automatic test discovery for unittest

Fuzzyman fuzzyman at gmail.com
Sat Jun 20 21:23:17 CEST 2009


The discover module is a backport of the automatic test discovery from
python-trunk (what will become Python 2.7 & 3.2) to work with Python
2.4 or more recent (including Python 3.0).

Test discovery allows you to run all the unittest based tests (or just
a subset of them) in your project without you having to write your own
test collection or running machinery. Once installed, test discovery
can be invoked with ``python -m discover``. I've tested the discover
module with Python 2.4 and 3.0.

The discover module also implements the ``load_tests`` protocol which
allows you to customize test loading from modules and packages. Test
discovery and ``load_tests`` are implemented in the
``DiscoveringTestLoader`` which can be used from your own test
framework.

* discover module on PyPI http://pypi.python.org/pypi/discover

discover can be installed with pip or easy_install. After installing
switch the
current directory to the top level directory of your project and run::

   python -m discover
   python discover.py

This will discover all tests (with certain restrictions) from the
current
directory. The discover module has several options to control its
behavior (full
usage options are displayed with ``python -m discover -h``)::

    Usage: discover.py [options]

    Options:
      -v, --verbose    Verbose output
      -s directory     Directory to start discovery ('.' default)
      -p pattern       Pattern to match test files ('test*.py'
default)
      -t directory     Top level directory of project (default to
                       start directory)

    For test discovery all test modules must be importable from the
top
    level directory of the project.

For example to use a different pattern for matching test modules run::

    python -m discover -p '*test.py'

(Remember to put quotes around the test pattern or shells like bash
will do
shell expansion rather than passing the pattern through to discover.)

Test discovery is implemented in
``discover.DiscoveringTestLoader.discover``. As
well as using discover as a command line script you can import
``DiscoveringTestLoader``, which is a subclass of
``unittest.TestLoader``, and
use it in your test framework.

This method finds and returns all test modules from the specified
start
directory, recursing into subdirectories to find them. Only test files
that
match *pattern* will be loaded. (Using shell style pattern matching.)

All test modules must be importable from the top level of the project.
If
the start directory is not the top level directory then the top level
directory must be specified separately.

The ``load_tests`` protocol allows test modules and packages to
customize how
they are loaded. This is implemented in
``discover.DiscoveringTestLoader.loadTestsFromModule``. If a test
module defines
a ``load_tests`` function then tests are loaded from the module by
calling
``load_tests`` with three arguments: `loader`, `standard_tests`,
`None`.

If a test package name (directory with `__init__.py`) matches the
pattern then the package will be checked for a ``load_tests``
function. If this exists then it will be called with *loader*,
*tests*,
*pattern*.

If ``load_tests`` exists then discovery does  *not* recurse into the
package,
``load_tests`` is responsible for loading all tests in the package.

The pattern is deliberately not stored as a loader attribute so that
packages can continue discovery themselves. *top_level_dir* is stored
so
``load_tests`` does not need to pass this argument in to
``loader.discover()``.

discover.py is maintained in a google code project (where bugs and
feature
requests should be posted): http://code.google.com/p/unittest-ext/

The latest development version of discover.py can be found at:
http://code.google.com/p/unittest-ext/source/browse/trunk/discover.py

Michael Foord


More information about the Python-announce-list mailing list