diff options
-rw-r--r-- | coverage/cmdline.py | 14 | ||||
-rw-r--r-- | coverage/control.py | 10 | ||||
-rw-r--r-- | coverage/xml.py | 49 |
3 files changed, 40 insertions, 33 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py index ab74d318..fd697344 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -242,6 +242,17 @@ CMDS = { usage = "[options] <pyfile> [program options]", description = "Run a python program, measuring code execution." ), + + 'xml': CmdOptionParser("xml", + [ + Opts.ignore_errors, + Opts.omit, + Opts.help, + ] + cmd = "xml", + usage = "[options]", + description = "Generate an XML report of coverage results." + ), } @@ -402,6 +413,8 @@ class CoverageScript: if 'html' in options.actions: self.coverage.html_report( directory=options.directory, **report_args) + if 'xml' in options.actions: + self.coverage.xml_report(**report_args) return OK @@ -470,6 +483,7 @@ Commands: html Create an HTML report. report Report coverage stats on modules. run Run a Python program and measure code execution. + xml Create an XML report of coverage results. Use "coverage help <command>" for detailed help on each command. For more information, see http://nedbatchelder.com/code/coverage diff --git a/coverage/control.py b/coverage/control.py index 2cfde279..519be1bb 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -10,6 +10,7 @@ from coverage.files import FileLocator from coverage.html import HtmlReporter from coverage.misc import format_lines, CoverageException from coverage.summary import SummaryReporter +from coverage.xml import XmlReporter class coverage: """Programmatic access to Coverage. @@ -318,3 +319,12 @@ class coverage: reporter = HtmlReporter(self, ignore_errors) reporter.report( morfs, directory=directory, omit_prefixes=omit_prefixes) + + def xml_report(self, morfs=None, ignore_errors=False, omit_prefixes=None): + """Generate an XML report of coverage results. + + The report is compatible with Cobertura reports. + + """ + reporter = XmlReporter(self, ignore_errors) + reporter.report(morfs, omit_prefixes=omit_prefixes) diff --git a/coverage/xml.py b/coverage/xml.py index acbd7124..55fdc973 100644 --- a/coverage/xml.py +++ b/coverage/xml.py @@ -1,17 +1,16 @@ -"""Cobertura reporting""" +"""Cobertura reporting for coverage.py""" -import os -import sys +import os, sys import xml.dom.minidom from coverage.report import Reporter -class CoberturaReporter(Reporter): - """A reporter for writing the summary report.""" +class XmlReporter(Reporter): + """A reporter for writing Cobertura-style XML coverage results.""" def __init__(self, coverage, ignore_errors=False): - super(CoberturaReporter, self).__init__(coverage, ignore_errors) + super(XmlReporter, self).__init__(coverage, ignore_errors) def report(self, morfs, omit_prefixes=None, outfile=None): """Generate a Cobertura report for `morfs`. @@ -21,15 +20,12 @@ class CoberturaReporter(Reporter): modules to omit from the report. """ - # - # Initial setup - # + # Initial setup. if not outfile: outfile = sys.stdout self.find_code_units(morfs, omit_prefixes) - # - # Create the DOM that will store the data - # + + # Create the DOM that will store the data. impl = xml.dom.minidom.getDOMImplementation() docType = impl.createDocumentType( "coverage", None, @@ -43,10 +39,8 @@ class CoberturaReporter(Reporter): errors = False for cu in self.code_units: - # # Create the 'lines' and 'package' XML elements, which # are populated later. Note that a package == a directory. - # (dir, fname) = os.path.split(cu.name) print "HERE",dir,":",fname if dir is '': @@ -65,24 +59,21 @@ class CoberturaReporter(Reporter): try: statements, _, missing, readable = self.coverage._analyze(cu) - # - # for each statement, create an XML 'line' element - # + + # For each statement, create an XML 'line' element. for line in statements: l = doc.createElement("line") l.setAttribute("number", str(line)) - # + # Q: can we get info about the number of times # a statement is executed? If so, that should be # recorded here. - # if not line in missing: l.setAttribute("hits", str(1)) - # + # Q: can we get info about whether this statement # is a branch? If so, that data should be # used here. - # l.setAttribute("branch", "false") lines.appendChild(l) class_lines = 1.0*len(statements) @@ -90,10 +81,8 @@ class CoberturaReporter(Reporter): class_branches = 0.0 class_branch_hits = 0.0 - # # Finalize the statistics that are collected # in the XML DOM. - # c.setAttribute("line-rate", str(class_hits / (class_lines or 1.0))) c.setAttribute( "branch-rate", str(class_branch_hits / (class_branches or 1.0)) ) package[1][className] = c @@ -110,15 +99,11 @@ class CoberturaReporter(Reporter): outfile.write(fmt_err % (cu.name, typ.__name__, msg)) errors=True - # - # Don't write the XML data if we've encountered errors - # + # Don't write the XML data if we've encountered errors. if errors: return - # - # Populate the XML DOM with the package info - # + # Populate the XML DOM with the package info. for packageName, packageData in packages.items(): package = packageData[0]; packageXml.appendChild(package) @@ -133,7 +118,5 @@ class CoberturaReporter(Reporter): package.setAttribute( "branch-rate", str(packageData[4] / (packageData[5] or 1.0) )) package.setAttribute("complexity", "0.0") - # - # Use the DOM to write the output file - # - outfile.write( doc.toprettyxml() ) + # Use the DOM to write the output file. + outfile.write(doc.toprettyxml()) |