This page is orignally from http://www.garethrees.org/2001/12/04/python-coverage, which seems to be defunct. I grabbed the text from archive.org, and present it here for posterity. I've updated the links to point to appropriate pages on this site.

www.garethrees.org / Software

Statement coverage for Python

Gareth Rees, Ravenbrook Limited, 2001-12-04

1. Introduction

The coverage.py Python module provides statement coverage for Python. It accumulates coverage data over many runs; generates coverage reports; and annotates Python source showing which statements have been covered.

To use it, download coverage.py and add it to your Python library (for example, in /usr/local/lib/python-version/lib/site-packages/) and your execution path.

See [GDR 2001-12-04] for design and analysis.

2. Command-line interface

Use the -x option (--execute) to execute a Python module with command-line arguments, and record coverage information:

$ coverage.py -x module.py [ARG1 ARG2 ...]

Coverage information accumulates over a sequence of executions, in the file .coverage (set the COVERAGE_FILE environment variable if you want to use a different file). To erase the recorded coverage information, use the -e option (--erase):

$ coverage.py -e

To report on the statement coverage for a set of files, use the -r option (--report):

$ coverage.py -r [-m] FILE1 FILE2 ...

Specify the -m option (--show-missing) to show the the line numbers of statements that weren't excecuted. For example:

$ coverage.py -e
$ coverage.py -x test_foo.py
Test errors (test_foo.error) ... ok
Test options (test_foo.options) ... ok
--------------------------------------
Ran 1 test in 0.966s

OK
$ coverage.py -r -m foo.py bar.py
Name    Stmts   Exec  Cover  Missing
------------------------------------
foo        64     56    87%  23, 57, 85, 119, 125, 133, 137, 152
bar       105     90    86%  78-86, 237-246
------------------------------------
TOTAL     169    146    86%
$

To make a copy of source code annotated with > for statements that are executed, and ! for statements that are not, use the -a option (--annotate):

$ coverage.py -a FILE1 FILE2 ...

The annotated copy of file is written as file,cover. Normally each annotated copy is written in the same directory as the original. Add the -d DIRECTORY option (--directory=DIRECTORY) to create the annotated copies in specified directory. For example:

$ coverage.py -a -d . /project/src/foo.py
$ cat foo.py,cover
...
>          length = self.msg.getheader('content-length')
>          if length:
>              try:
>                  self.length = int(length)
!              except ValueError:
!                  self.length = 0
>              self.length = max(self.length, 0)
!          else:
!              self.length = 0
...
$

3. Programmatic interface

When testing interactively, you'll need to use the programmatic interface.

Call start() to start recording coverage:

>>> import coverage
>>> coverage.start()

Stop recording by calling stop(). Call erase() to erase all results (including the .coverage file).

To calculate the coverage of a module or file, call analysis(), passing a module object or a filename. It returns a 4-tuple consisting of

  1. The module's filename.

  2. A list of line numbers of statements in the module.

  3. A list of line numbers of statements that weren't executed.

  4. A human-readable string describing the line numbers of statements that weren't executed, coalescing groups of adjacent statements.

For example:

>>> import coverage
>>> coverage.erase()
>>> coverage.start()
>>> import spong
>>> spong.run_tests()
>>> coverage.stop()
>>> coverage.analysis(spong)
('/project/foo/tests/foo.py',
 [10, 11, 12, 13, 17, 18, 20, 21, 23],
 [12, 13, 17, 21, 23],
 '12-17, 21-23')

report() prints a coverage report. Pass it a list of modules or filenames, and give optional argument ignore_errors = 1 to ignore errors in analyzing modules; and show_missing = 0 to hide the missing statements.

For example:

>>> coverage.report([foo, bar])
Name    Stmts   Exec  Cover  Missing
------------------------------------
foo        64     56    87%  23, 57, 85, 119, 125, 133, 137, 152
bar       105     90    86%  78-86, 237-246
------------------------------------
TOTAL     169    146    86%
>>> m = sys.modules.values()
>>> coverage.report(m, ignore_errors=1, show_missing=0)
Name       Stmts   Exec  Cover
------------------------------
types         47      0     0%
foo           64     56    87%
token        111      0     0%
whrandom      69     21    30%
bar          105     90    86%
coverage     141      2     1%
unittest     400     94    23%
string       121     15    12%
...

4. Limitations

A. References

[GDR 2001-12-04] "Statement coverage for Python: design and analysis"; Gareth Rees; Ravenbrook Limited; 2001-12-04; <http://www.garethrees.org/2001/12/04/python-coverage/design.html>.
[Kaner 2000-10-17] "Measurement of the extent of testing"; Cem Kaner; 2000-10-17; <http://www.kaner.com/pnsqc.html>.
[Marick 1997] "How to misuse code coverage"; Brian Marick; 1997; <http://www.testing.com/writings/coverage.pdf>.

B. Document History

2001-12-04 GDR Created.
2001-12-12 GDR Document -d option for annotation.

Copyright © 2001 Gareth Rees. Redistribution, with or without modification, is permitted provided that the copyright notice, conditions, and disclaimer are retained. This document is provided "as is", without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this document.

$Id: //info.ravenbrook.com/user/gdr/www.garethrees.org/2001/12/04/python-coverage/index.html#7 $

www.garethrees.org / Software