Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

pypm install z3c.coverage

How to install z3c.coverage

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install z3c.coverage
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
2.0.0Never BuiltWhy not?
1.3.1 Available View build log
1.2.0 Available View build log
Windows (64-bit)
2.0.0Never BuiltWhy not?
1.2.0 Available View build log
Mac OS X (10.5+)
2.0.0Never BuiltWhy not?
1.3.1 Available View build log
1.2.0 Available View build log
Linux (32-bit)
2.0.0 Available View build log
1.3.1 Available View build log
1.3.0 Available View build log
1.2.0 Available View build log
Linux (64-bit)
2.0.0 Available View build log
1.3.1 Available View build log
1.3.0 Available View build log
1.2.0 Available View build log
2.0.0 Available View build log
ZPL 2.1
Lastest release
version 2.0.0 on Feb 20th, 2013

This package contains tools to work with Python coverage data.

coveragereport produces HTML reports from coverage data, with syntax-highlighted source code and per-package aggregate numbers.

coveragediff compares two sets of coverage reports and reports regressions, that is, increases in the number of untested lines of code.

Using coveragereport

$ coveragereport --help
Usage: coveragereport [options] [inputpath [outputdir]]

Converts coverage reports to HTML.  If the input path is omitted, it defaults
to coverage or .coverage, whichever exists.  If the output directory is
omitted, it defaults to inputpath + /report or ./coverage-reports, depending
on whether the input path points to a directory or a file.

  -h, --help            show this help message and exit
  -q, --quiet           be quiet
  -v, --verbose         be verbose (default)
                        strip base directory from filenames loaded from
                        define path mappings for filenames loaded from

Example use with zope.testrunner:

$ bin/test --coverage=coverage
$ coveragereport
$ ln -s mypackage.html coverage/report/index.html
$ xdg-open coverage/report/index.html
$ xdg-open coverage/report/all.html

Example use with nose and coverage.py:

$ nosetests --with-coverage --cover-erase
$ coveragereport --strip-prefix=/full/path/to/source/
$ ln -s mypackage.html coverage-reports/index.html
$ xdg-open coverage-reports/index.html
$ xdg-open coverage-reports/all.html

Sample report:



You need enscript installed and available in your $PATH if you want syntax highlighting.

Using coveragediff

Usage: coveragediff [options] olddir newdir

  -h, --help         show this help message and exit
  --include=REGEX    only consider files matching REGEX
  --exclude=REGEX    ignore files matching REGEX
  --email=ADDR       send the report to a given email address (only if
                     regressions were found)
  --from=ADDR        set the email sender address
  --subject=SUBJECT  set the email subject
  --web-url=BASEURL  include hyperlinks to HTML-ized coverage reports at a
                     given URL

Usage example with zope.testrunner:

$ bin/test --coverage=coverage
$ vi src/...
$ mv coverage coverage.old
$ bin/test --coverage=coverage
$ coveragediff coverage.old coverage

You cannot use coveragediff with coverage.py data. More on that below.

Output example:

$ coveragediff coverage.old coverage
my.package.module: 36 new lines of untested code
my.package.newmodule: new file with 15 lines of untested code (out of 23)

Output with clickable links:

$ coveragediff coverage.old coverage --web-url=http://example.com/coverage
my.package.module: 36 new lines of untested code
See http://example.com/coverage/my.package.module.html

my.package.newmodule: new file with 15 lines of untested code (out of 23)
See http://example.com/coverage/my.package.newmodule.html

Output via email, convenient for continuous integration:

$ coveragediff coverage.old coverage --web-url=http://example.com/coverage \
                   --email 'Developers <dev@exmaple.com>' \
                   --from 'Buildbot <buildbot@example.com>'

That last example doesn't produce any output, but sends an email (via SMTP to localhost:25).

Getting coverage data


zope.testrunner can produce a directory full of files named dotted.package.name.cover that contain source code annotated with coverage information. To get them, use

bin/test --coverage=outdir/

Both coveragereport and coveragediff accept this as inputs.


coverage.py can produce a .coverage file, which is actually a Python pickle containing (incomplete) coverage information. To get it, use

coverage run bin/testrunner

coveragereport can take the .coverage file as an input, but it also needs access to the matching source files. And you have to manually specify the absolute pathname prefix of your source tree so that the report know how to translate filenames into dotted package names. Also, it's not enough to have absolute pathnames, you need to supply the canonical absolute pathname (with no symlink segments), such as returned by os.path.realpath. This is very inconvenient. Sorry.

coveragediff is unable to compare two .coverage files and report regressions. One reason for that is the incompleteness of the data format (the pickle contains line numbers of executed statements, but doesn't say which lines contain code and which ones are blank/comments/continuation lines/excluded source lines). The other reason is simpler: nobody wrote the code. ;)

Unfortunately coverage annotate does not produce files compatible with coveragereport/coveragediff. This could also be remedied if somebody wrote a patch.


If you want to use a .coverage file produced on another machine or simply in a different working directory, you will need to tell coveragereport how to adjust the absolute filenames so that the sources can be found. Use the --path-alias option for that. Alternatively you could use coverage combine to manipulate the .coverage file itself, as described in the documentation.


.coverage files are Python pickles, which has important security ramifications. You can craft a Pickle file that executes arbitrary code during load time. Do not ever attempt to use pickles received from untrusted sources.


The *.cover annotated-source format produced by zope.testrunner actually comes from the Python standard library module trace.py. You can probably use trace.py directly. I've never tried.

Frequently Asked Questions

Why use z3c.coverage instead of coverage html?

Some people prefer the look of the reports produced by z3c.coverage. Some people find per-package coverage summaries or the tree-like navigation convenient.

Should I use zope.testrunner's built-in coverage, or coverage run bin/test?

coverage.py is much faster, but using it (and hooking it up to z3c.coverage) is perhaps less convenient. E.g. if you use zc.buildout 1.5.x with zc.recipe.testrunner, you will be unable to use coverage run bin/test because of mystic semi-broken site isolation magic of the former.


2.0.0 (2013-02-20)
  • Added Python 3.3 and PyPy 1.9 support.
  • Dropped Python 2.4 and 2.5 support.
1.3.1 (2012-10-24)
  • Nicer PyPI description. Doctests are tests, not docs.
  • coveragereport now accepts --path-alias.
  • coveragereport: new color step between yellow (90%) and green (100%), a yellowish-green (95%).
1.3.0 (2012-09-06)
  • coveragereport now accepts --help, --verbose and --quiet options, with verbose being on by default.
  • coveragereport now can handle .coverage files produced by http://pypi.python.org/pypi/coverage
  • Bugfix: sorting by numbered of uncovered lines was broken in the all.html report.
1.2.0 (2010-02-11)
  • Rename the coverage script to coveragereport, to avoid name clashes with Ned Batchelder's excellent coverage.py.
1.1.3 (2009-07-24)
  • Bug: Doctest did not normalize the whitespace in coveragediff.txt. For some reason it passes while testing independently, but when running all tests, it failed.
1.1.2 (2008-04-14)
  • Bug: When a package path contained anywhere the word "test", it was ignored from the coverage report. The intended behavior, however, was to ignore files that relate to setting up tests.
  • Bug: Sort the results of os.listdir() in README.txt to avoid non-deterministic failures.
  • Bug: The logic for ignoring unit and functional test modules also used to ignore modules and packages called testing.
  • Change "Unit test coverage" to "Test coverage" in the title -- it works perfectly fine for functional tests too.
1.1.1 (2008-01-31)
  • Bug: When the package was released, the test which tests the availability of an SVN revision number failed. Made the test more reliable.
1.1.0 (2008-01-29)
  • Feature: The main() coverage report function now accepts the arguments of the script as a function argument, making it easier to configure the script from buildout.
  • Feature: When the report directory does not exist, the report generator creates it for you.
  • Feature: Eat your own dog food by creating a buildout that can create coverage reports.
  • Bug: Improved the test coverage to 100%.
1.0.1 (2007-09-26)
  • Bug: Fixed meta-data.
1.0.0 (2007-09-26)
  • First public release.
  • Feature: Added the --web option to coveragediff.
  • Feature: Added a test suite.
  • Feature: Added coveragediff.py.
  • Initial release of coveragereport.py.

Subscribe to package updates

Last updated Feb 20th, 2013

Download Stats

Last month:3

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.