Source code for nose2.plugins.coverage

"""
Use this plugin to activate coverage report.

To use this plugin, you need to install ``nose2[coverage_plugin]``. e.g.

::

    $ pip install nose2[coverage_plugin]>=0.6.5


Then, you can enable coverage reporting with :

::

    $ nose2 --with-coverage

Or with this lines in ``unittest.cfg`` :

::

    [coverage]
    always-on = True

"""
from __future__ import absolute_import
import logging

from nose2.events import Plugin

log = logging.getLogger(__name__)


[docs]class Coverage(Plugin): configSection = 'coverage' commandLineSwitch = ('C', 'with-coverage', 'Turn on coverage reporting') def __init__(self): """Get our config and add our command line arguments.""" self.conSource = self.config.as_list('coverage', []) self.conReport = self.config.as_list('coverage-report', []) self.conConfig = self.config.as_str('coverage-config', '').strip() group = self.session.pluginargs group.add_argument( '--coverage', action='append', default=[], metavar='PATH', dest='coverage_source', help='Measure coverage for filesystem path (multi-allowed)' ) group.add_argument( '--coverage-report', action='append', default=[], metavar='TYPE', choices=['term', 'term-missing', 'annotate', 'html', 'xml'], dest='coverage_report', help='Generate selected reports, available types:' ' term, term-missing, annotate, html, xml (multi-allowed)' ) group.add_argument( '--coverage-config', action='store', default='', metavar='FILE', dest='coverage_config', help='Config file for coverage, default: .coveragerc' ) self.covController = None
[docs] def handleArgs(self, event): """Get our options in order command line, config file, hard coded.""" self.covSource = (event.args.coverage_source or self.conSource or ['.']) self.covReport = (event.args.coverage_report or self.conReport or ['term']) self.covConfig = (event.args.coverage_config or self.conConfig or '.coveragerc')
[docs] def createTests(self, event): """Start coverage early to catch imported modules. Only called if active so, safe to just start without checking flags""" try: import coverage except ImportError: print('Warning: you need to install "coverage_plugin" ' 'extra requirements to use this plugin. ' 'e.g. `pip install nose2[coverage_plugin]`') return if event.handled: log.error( 'createTests already handled -- ' 'coverage reporting will be inaccurate') else: log.debug( 'createTests not already handled. coverage should work') self.covController = coverage.Coverage(source=self.covSource, config_file=self.covConfig) # start immediately (don't wait until startTestRun) so that coverage # will pick up on things which happen at import time self.covController.start()
[docs] def afterSummaryReport(self, event): """Only called if active so stop coverage and produce reports.""" if self.covController: self.covController.stop() # write to .coverage file # do this explicitly (instead of passing auto_data=True to # Coverage constructor) in order to not load an existing .coverage # this better imitates the behavior of invoking `coverage` from the # command-line, which sets `Coverage._auto_save` (triggers atexit # saving to this file), but not `Coverage._auto_load` # requesting a better fix in nedbat/coveragepy#34 self.covController.save() if 'term' in self.covReport or 'term-missing' in self.covReport: # only pass `show_missing` if "term-missing" was given # otherwise, just allow coverage to load show_missing from # config kwargs = {} if 'term-missing' in self.covReport: kwargs['show_missing'] = True self.covController.report(file=event.stream, **kwargs) if 'annotate' in self.covReport: self.covController.annotate() if 'html' in self.covReport: self.covController.html_report() if 'xml' in self.covReport: self.covController.xml_report()