diff options
-rw-r--r-- | coverage/cmdline.py | 5 | ||||
-rw-r--r-- | doc/branch.rst | 3 | ||||
-rw-r--r-- | doc/config.rst | 68 | ||||
-rw-r--r-- | doc/excluding.rst | 34 | ||||
-rw-r--r-- | doc/index.rst | 1 | ||||
-rw-r--r-- | doc/subprocess.rst | 47 |
6 files changed, 130 insertions, 28 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py index f7cb28c3..0ab74759 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -61,8 +61,9 @@ class Opts(object): ) parallel_mode = optparse.Option( '-p', '--parallel-mode', action='store_true', - help="Include the machine name and process id in the .coverage " - "data file name." + help="Append the machine name, process id and random number to the " + ".coverage data file name to simplify collecting data from " + "many processes." ) rcfile = optparse.Option( '', '--rcfile', action='store', diff --git a/doc/branch.rst b/doc/branch.rst index a7f95e7d..71681317 100644 --- a/doc/branch.rst +++ b/doc/branch.rst @@ -6,6 +6,9 @@ Branch coverage measurement :history: 20091127T201300, new for version 3.2 +.. highlight:: python + :linenothreshold: 5 + Coverage.py now supports branch coverage measurement. Where a line in your program could jump to more than one next line, coverage.py tracks which of diff --git a/doc/config.rst b/doc/config.rst index 355cf449..ada6d088 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -23,14 +23,44 @@ A coverage.py configuration file is in classic .ini file format: sections are introduced by a ``[section]`` header, and contain ``name = value`` entries. Lines beginning with ``#`` or ``;`` are ignored as comments. -Multi-line entries can be created by indenting values on multiple lines. +Strings don't need quotes. Multi-strings can be created by indenting values on +multiple lines. Boolean values can be specified as ``on``, ``off``, ``true``, ``false``, ``1``, -or ``0``. +or ``0`` and are case-insensitive. Many sections and values correspond roughly to commands and options in the command-line interface. +Here's a sample configuration file:: + + # .coveragerc to control coverage.py + [run] + branch = True + + [report] + # Regexes for lines to exclude from consideration + exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + + # Don't complain about missing debug-only code: + def __repr__ + if self\.debug + + # Don't complain if tests don't hit defensive assertion code: + raise AssertionError + raise NotImplementedError + + # Don't complain if non-runnable code isn't run: + if 0: + if __name__ == .__main__.: + + ignore_errors = True + + [html] + directory = coverage_html_report + [run] ----- @@ -38,16 +68,21 @@ command-line interface. These values are generally used when running product code, though some apply to more than one command. -``branch`` (boolean): whether to measure :ref:`branch coverage <branch>`. +``branch`` (boolean, default False): whether to measure +:ref:`branch coverage <branch>` in addition to statement coverage. -``cover_pylib`` (boolean): whether to measure the Python standard library. +``cover_pylib`` (boolean, default False): whether to measure the Python +standard library. -``data_file`` (string): the name of the data file to use for storing or -reporting coverage. +``data_file`` (string, default ".coverage"): the name of the data file to use +for storing or reporting coverage. -``parallel`` (boolean): +``parallel`` (boolean, default False): append the machine name, process +id and random number to the data file name to simplify collecting data from +many processes. -``timid`` (boolean): +``timid`` (boolean, default False): use a simpler but slower trace method. +Try this if you get seemingly impossible results. [report] @@ -55,11 +90,17 @@ reporting coverage. Values common to many kinds of reporting. -``exclude_lines`` (multi-string): +``exclude_lines`` (multi-string): a list of regular expressions. Any line of +your source code that matches one of these regexes is excluded from being +reported as missing. More details are in :ref:`excluding`. If you use this +option, you are replacing all the exclude regexes, so you'll need to also +supply the "pragma: no cover" regex if you still want to use it. -``ignore_errors`` (boolean): +``ignore_errors`` (boolean, default False): ignore source code that can't be +found. -``omit`` (multi-string): +``omit`` (multi-string): a list of file prefixes. If a source file begins with +one of these prefixes, it will be omitted from the report. [html] @@ -67,7 +108,7 @@ Values common to many kinds of reporting. Values particular to HTML reporting. -``directory`` (string): +``directory`` (string, default "htmlcov"): where to write the HTML report files. [xml] @@ -75,5 +116,4 @@ Values particular to HTML reporting. Values particular to XML reporting. -``output`` (string): - +``output`` (string, default "coverage.xml"): where to write the XML report. diff --git a/doc/excluding.rst b/doc/excluding.rst index 1b91fc9a..55acebeb 100644 --- a/doc/excluding.rst +++ b/doc/excluding.rst @@ -5,6 +5,8 @@ Excluding code from coverage ============================ :history: 20090613T090500, brand new docs. +:history: 20100224T200900, updated for 3.3. + You may have code in your project that you know won't be executed, and you want to tell coverage to ignore it. For example, you may have debugging-only code @@ -61,23 +63,31 @@ Advanced exclusion ------------------ Coverage identifies exclusions by matching lines against a list of regular -expressions. Using the coverage :ref:`API <api>`, you can add to that list. -This is useful if you have often-used constructs to exclude that can be matched -with a regex. You can exclude them all at once without littering your code with -exclusion pragmas. +expressions. Using :ref:`configuration files <config>` or the coverage +:ref:`API <api>`, you can add to that list. This is useful if you have +often-used constructs to exclude that can be matched with a regex. You can +exclude them all at once without littering your code with exclusion pragmas. For example, you might decide that __repr__ functions are usually only used in debugging code, and are uninteresting to test themselves. You could exclude all of them by adding a regex to the exclusion list:: - coverage.exclude('def __repr__') + [report] + exclude_lines = def __repr__ Here's a list of exclusions I've used:: - coverage.exclude('def __repr__') - coverage.exclude('if self.debug:') - coverage.exclude('if settings.DEBUG') - coverage.exclude('raise AssertionError') - coverage.exclude('raise NotImplementedError') - coverage.exclude('if 0:') - coverage.exclude('if __name__ == .__main__.:') + [report] + exclude_lines = + pragma: no cover + def __repr__ + if self.debug: + if settings.DEBUG + raise AssertionError + raise NotImplementedError + if 0: + if __name__ == .__main__.: + +Note that when using the ``exclude_lines`` option in a configuration file, you +are taking control of the entire list of regexes, so you need to re-specify the +default "pragma: no cover" match if you still want it to apply. diff --git a/doc/index.rst b/doc/index.rst index f179acb5..f1e49e7e 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -108,6 +108,7 @@ More information api excluding branch + subprocess faq changes diff --git a/doc/subprocess.rst b/doc/subprocess.rst new file mode 100644 index 00000000..d976f692 --- /dev/null +++ b/doc/subprocess.rst @@ -0,0 +1,47 @@ +.. _subprocess: + +====================== +Measuring subprocesses +====================== + +:history: 20100224T201800, new for 3.3. + + +Complex test suites may spawn subprocesses to run tests, either to run them in +parallel, or because subprocess behavior is an important part of the code under +test. Measuring coverage in those subprocesses can be tricky because you have +to modify the code spawning the process to invoke coverage.py. + +There's an easier way to do it: coverage.py includes a function, +:func:`coverage.process_startup` designed to be invoked when Python starts. It +examines the ``COVERAGE_PROCESS_START`` environment variable, and if it is set, +begins coverage measurement. Its value will be used as the name of the +:ref:`configuration file <config>` to use. + +When using this technique, be sure to set the parallel option to true so that +multiple coverage.py runs will each write their data to a distinct file. + + +Configuring Python for subprocess coverage +------------------------------------------ + +You can configure your Python installation to invoke the ``process_startup`` +function in two ways: + +#. Create or append to sitecustomize.py to add these lines:: + + import coverage + coverage.process_startup() + +#. Create a .pth file in your Python installation containing:: + + import coverage; coverage.process_startup() + +The sitecustomize.py technique is cleaner, but may involve modifying an existing +sitecustomize.py, since there can be only one. If there is no sitecustomize.py +already, you can create it in any directory on the Python path. + +The .pth technique seems like a hack, but works, and is documented behavior. +On the plus side, you can create the file with any name you like so you don't +have to coordinate with other .pth files. On the minus side, you have to create +the file in a system-defined directory, so you may need privileges to write it. |