summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/cmdline.py7
-rw-r--r--coverage/config.py2
-rw-r--r--coverage/control.py11
-rw-r--r--coverage/summary.py205
-rw-r--r--doc/cmd.rst3
-rw-r--r--tests/test_cmdline.py2
-rw-r--r--tests/test_summary.py125
7 files changed, 263 insertions, 92 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index 65ee73f8..89b0807d 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -96,6 +96,10 @@ class Opts:
'', '--fail-under', action='store', metavar="MIN", type="float",
help="Exit with a status of 2 if the total coverage is less than MIN.",
)
+ output_format = optparse.make_option(
+ '', '--format', action='store', metavar="FORMAT", dest="output_format",
+ help="Output format, either text (default) or markdown",
+ )
help = optparse.make_option(
'-h', '--help', action='store_true',
help="Get help on this command.",
@@ -245,6 +249,7 @@ class CoverageOptionParser(optparse.OptionParser):
debug=None,
directory=None,
fail_under=None,
+ output_format=None,
help=None,
ignore_errors=None,
include=None,
@@ -482,6 +487,7 @@ COMMANDS = {
Opts.contexts,
Opts.input_datafile,
Opts.fail_under,
+ Opts.output_format,
Opts.ignore_errors,
Opts.include,
Opts.omit,
@@ -689,6 +695,7 @@ class CoverageScript:
skip_covered=options.skip_covered,
skip_empty=options.skip_empty,
sort=options.sort,
+ output_format=options.output_format,
**report_args
)
elif options.action == "annotate":
diff --git a/coverage/config.py b/coverage/config.py
index c2375d03..1f239ea3 100644
--- a/coverage/config.py
+++ b/coverage/config.py
@@ -199,6 +199,7 @@ class CoverageConfig:
# Defaults for [report]
self.exclude_list = DEFAULT_EXCLUDE[:]
self.fail_under = 0.0
+ self.output_format = None
self.ignore_errors = False
self.report_include = None
self.report_omit = None
@@ -374,6 +375,7 @@ class CoverageConfig:
# [report]
('exclude_list', 'report:exclude_lines', 'regexlist'),
('fail_under', 'report:fail_under', 'float'),
+ ('output_format', 'report:output_format', 'boolean'),
('ignore_errors', 'report:ignore_errors', 'boolean'),
('partial_always_list', 'report:partial_branches_always', 'regexlist'),
('partial_list', 'report:partial_branches', 'regexlist'),
diff --git a/coverage/control.py b/coverage/control.py
index 91e604e0..a8cf1649 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -908,7 +908,8 @@ class Coverage:
def report(
self, morfs=None, show_missing=None, ignore_errors=None,
file=None, omit=None, include=None, skip_covered=None,
- contexts=None, skip_empty=None, precision=None, sort=None
+ contexts=None, skip_empty=None, precision=None, sort=None,
+ output_format=None,
):
"""Write a textual summary report to `file`.
@@ -922,6 +923,9 @@ class Coverage:
`file` is a file-like object, suitable for writing.
+ `output_format` provides options, to print eitehr as plain text, or as
+ markdown code
+
`include` is a list of file name patterns. Files that match will be
included in the report. Files matching `omit` will not be included in
the report.
@@ -953,13 +957,16 @@ class Coverage:
.. versionadded:: 5.2
The `precision` parameter.
+ .. versionadded:: 6.6
+ The `format` parameter.
+
"""
with override_config(
self,
ignore_errors=ignore_errors, report_omit=omit, report_include=include,
show_missing=show_missing, skip_covered=skip_covered,
report_contexts=contexts, skip_empty=skip_empty, precision=precision,
- sort=sort
+ sort=sort, output_format=output_format,
):
reporter = SummaryReporter(self)
return reporter.report(morfs, outfile=file)
diff --git a/coverage/summary.py b/coverage/summary.py
index 861fbc53..94be1a08 100644
--- a/coverage/summary.py
+++ b/coverage/summary.py
@@ -6,7 +6,7 @@
import sys
from coverage.exceptions import ConfigError, NoDataError
-from coverage.misc import human_sorted_items
+from coverage.misc import human_key
from coverage.report import get_analysis_to_report
from coverage.results import Numbers
@@ -30,6 +30,119 @@ class SummaryReporter:
self.outfile.write(line.rstrip())
self.outfile.write("\n")
+ def _report_text(self, header, lines_values, total_line, end_lines):
+ """Internal method that prints report data in text format.
+
+ `header` is a tuple with captions.
+ `lines_values` is list of tuples of sortable values.
+ `total_line` is a tuple with values of the total line.
+ `end_lines` is a tuple of ending lines with information about skipped files.
+
+ """
+ # Prepare the formatting strings, header, and column sorting.
+ max_name = max([len(line[0]) for line in lines_values] + [5]) + 1
+ max_n = max(len(total_line[header.index("Cover")]) + 2, len(" Cover")) + 1
+ max_n = max([max_n] + [len(line[header.index("Cover")]) + 2 for line in lines_values])
+ h_form = dict(
+ Name="{:{name_len}}",
+ Stmts="{:>7}",
+ Miss="{:>7}",
+ Branch="{:>7}",
+ BrPart="{:>7}",
+ Cover="{:>{n}}",
+ Missing="{:>10}",
+ )
+ header_items = [
+ h_form[item].format(item, name_len=max_name, n=max_n)
+ for item in header
+ ]
+ header_str = "".join(header_items)
+ rule = "-" * len(header_str)
+
+ # Write the header
+ self.writeout(header_str)
+ self.writeout(rule)
+
+ h_form.update(dict(Cover="{:>{n}}%"), Missing=" {:9}")
+ for values in lines_values:
+ # build string with line values
+ line_items = [
+ h_form[item].format(str(value),
+ name_len=max_name, n=max_n-1) for item, value in zip(header, values)
+ ]
+ text = "".join(line_items)
+ self.writeout(text)
+
+ # Write a TOTAL line
+ self.writeout(rule)
+ line_items = [
+ h_form[item].format(str(value),
+ name_len=max_name, n=max_n-1) for item, value in zip(header, total_line)
+ ]
+ text = "".join(line_items)
+ self.writeout(text)
+
+ for end_line in end_lines:
+ self.writeout(end_line)
+
+ def _report_markdown(self, header, lines_values, total_line, end_lines):
+ """Internal method that prints report data in markdown format.
+
+ `header` is a tuple with captions.
+ `lines_values` is a sorted list of tuples containing coverage information.
+ `total_line` is a tuple with values of the total line.
+ `end_lines` is a tuple of ending lines with information about skipped files.
+
+ """
+ # Prepare the formatting strings, header, and column sorting.
+ max_name = max([len(line[0].replace("_", "\\_")) for line in lines_values] + [9])
+ max_name += 1
+ h_form = dict(
+ Name="| {:{name_len}}|",
+ Stmts="{:>9} |",
+ Miss="{:>9} |",
+ Branch="{:>9} |",
+ BrPart="{:>9} |",
+ Cover="{:>{n}} |",
+ Missing="{:>10} |",
+ )
+ max_n = max(len(total_line[header.index("Cover")]) + 6, len(" Cover "))
+ header_items = [h_form[item].format(item, name_len=max_name, n=max_n) for item in header]
+ header_str = "".join(header_items)
+ rule_str = "|" + " ".join(["- |".rjust(len(header_items[0])-1, '-')] +
+ ["-: |".rjust(len(item)-1, '-') for item in header_items[1:]]
+ )
+
+ # Write the header
+ self.writeout(header_str)
+ self.writeout(rule_str)
+
+ for values in lines_values:
+ # build string with line values
+ h_form.update(dict(Cover="{:>{n}}% |"))
+ line_items = [
+ h_form[item].format(str(value).replace("_", "\\_"),
+ name_len=max_name, n=max_n-1) for item, value in zip(header, values)
+ ]
+ text = "".join(line_items)
+ self.writeout(text)
+
+ # Write the TOTAL line
+ h_form.update(dict(Name="|{:>{name_len}} |", Cover="{:>{n}} |"))
+ total_line_items = []
+ for item, value in zip(header, total_line):
+ if value == '':
+ insert = value
+ elif item == "Cover":
+ insert = f" **{value}%**"
+ else:
+ insert = f" **{value}**"
+ total_line_items += h_form[item].format(insert, name_len=max_name, n=max_n)
+ total_row_str = "".join(total_line_items)
+ self.writeout(total_row_str)
+ for end_line in end_lines:
+ self.writeout(end_line)
+
def report(self, morfs, outfile=None):
"""Writes a report summarizing coverage statistics per module.
@@ -44,36 +157,19 @@ class SummaryReporter:
self.report_one_file(fr, analysis)
# Prepare the formatting strings, header, and column sorting.
- max_name = max([len(fr.relative_filename()) for (fr, analysis) in self.fr_analysis] + [5])
- fmt_name = "%%- %ds " % max_name
- fmt_skip_covered = "\n%s file%s skipped due to complete coverage."
- fmt_skip_empty = "\n%s empty file%s skipped."
-
- header = (fmt_name % "Name") + " Stmts Miss"
- fmt_coverage = fmt_name + "%6d %6d"
+ header = ("Name", "Stmts", "Miss",)
if self.branches:
- header += " Branch BrPart"
- fmt_coverage += " %6d %6d"
- width100 = Numbers(precision=self.config.precision).pc_str_width()
- header += "%*s" % (width100+4, "Cover")
- fmt_coverage += "%%%ds%%%%" % (width100+3,)
+ header += ("Branch", "BrPart",)
+ header += ("Cover",)
if self.config.show_missing:
- header += " Missing"
- fmt_coverage += " %s"
- rule = "-" * len(header)
+ header += ("Missing",)
column_order = dict(name=0, stmts=1, miss=2, cover=-1)
if self.branches:
column_order.update(dict(branch=3, brpart=4))
- # Write the header
- self.writeout(header)
- self.writeout(rule)
-
- # `lines` is a list of pairs, (line text, line values). The line text
- # is a string that will be printed, and line values is a tuple of
- # sortable values.
- lines = []
+ # `lines_values` is list of tuples of sortable values.
+ lines_values = []
for (fr, analysis) in self.fr_analysis:
nums = analysis.numbers
@@ -84,12 +180,10 @@ class SummaryReporter:
args += (nums.pc_covered_str,)
if self.config.show_missing:
args += (analysis.missing_formatted(branches=True),)
- text = fmt_coverage % args
- # Add numeric percent coverage so that sorting makes sense.
args += (nums.pc_covered,)
- lines.append((text, args))
+ lines_values.append(args)
- # Sort the lines and write them out.
+ # line-sorting.
sort_option = (self.config.sort or "name").lower()
reverse = False
if sort_option[0] == '-':
@@ -97,41 +191,44 @@ class SummaryReporter:
sort_option = sort_option[1:]
elif sort_option[0] == '+':
sort_option = sort_option[1:]
-
+ sort_idx = column_order.get(sort_option)
+ if sort_idx is None:
+ raise ConfigError(f"Invalid sorting option: {self.config.sort!r}")
if sort_option == "name":
- lines = human_sorted_items(lines, reverse=reverse)
+ lines_values.sort(key=lambda tup: (human_key(tup[0]), tup[1]), reverse=reverse)
else:
- position = column_order.get(sort_option)
- if position is None:
- raise ConfigError(f"Invalid sorting option: {self.config.sort!r}")
- lines.sort(key=lambda l: (l[1][position], l[0]), reverse=reverse)
-
- for line in lines:
- self.writeout(line[0])
-
- # Write a TOTAL line if we had at least one file.
- if self.total.n_files > 0:
- self.writeout(rule)
- args = ("TOTAL", self.total.n_statements, self.total.n_missing)
- if self.branches:
- args += (self.total.n_branches, self.total.n_partial_branches)
- args += (self.total.pc_covered_str,)
- if self.config.show_missing:
- args += ("",)
- self.writeout(fmt_coverage % args)
+ lines_values.sort(key=lambda tup: (tup[sort_idx], tup[0]), reverse=reverse)
+
+ # calculate total if we had at least one file.
+ total_line = ("TOTAL", self.total.n_statements, self.total.n_missing)
+ if self.branches:
+ total_line += (self.total.n_branches, self.total.n_partial_branches)
+ total_line += (self.total.pc_covered_str,)
+ if self.config.show_missing:
+ total_line += ("",)
- # Write other final lines.
+ # create other final lines
+ end_lines = []
if not self.total.n_files and not self.skipped_count:
raise NoDataError("No data to report.")
if self.config.skip_covered and self.skipped_count:
- self.writeout(
- fmt_skip_covered % (self.skipped_count, 's' if self.skipped_count > 1 else '')
+ file_suffix = 's' if self.skipped_count>1 else ''
+ fmt_skip_covered = (
+ f"\n{self.skipped_count} file{file_suffix} skipped due to complete coverage."
)
+ end_lines.append(fmt_skip_covered)
if self.config.skip_empty and self.empty_count:
- self.writeout(
- fmt_skip_empty % (self.empty_count, 's' if self.empty_count > 1 else '')
- )
+ file_suffix = 's' if self.empty_count>1 else ''
+ fmt_skip_empty = f"\n{self.empty_count} empty file{file_suffix} skipped."
+ end_lines.append(fmt_skip_empty)
+
+ text_format = self.config.output_format or "text"
+ if text_format == "markdown":
+ formatter = self._report_markdown
+ else:
+ formatter = self._report_text
+ formatter(header, lines_values, total_line, end_lines)
return self.total.n_statements and self.total.pc_covered
diff --git a/doc/cmd.rst b/doc/cmd.rst
index f8de0cb3..fd1f7d1a 100644
--- a/doc/cmd.rst
+++ b/doc/cmd.rst
@@ -518,6 +518,7 @@ as a percentage.
file. Defaults to '.coverage'. [env: COVERAGE_FILE]
--fail-under=MIN Exit with a status of 2 if the total coverage is less
than MIN.
+ --format=FORMAT Output format, either text (default) or markdown
-i, --ignore-errors Ignore errors while reading source files.
--include=PAT1,PAT2,...
Include only files whose paths match one of these
@@ -540,7 +541,7 @@ as a percentage.
--rcfile=RCFILE Specify configuration file. By default '.coveragerc',
'setup.cfg', 'tox.ini', and 'pyproject.toml' are
tried. [env: COVERAGE_RCFILE]
-.. [[[end]]] (checksum: 2f8dde61bab2f44fbfe837aeae87dfd2)
+.. [[[end]]] (checksum: 8c671de502a388159689082d906f786a)
The ``-m`` flag also shows the line numbers of missing statements::
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index 305fbdbf..1b9a1ef0 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -44,7 +44,7 @@ class BaseCmdLineTest(CoverageTest):
_defaults.Coverage().report(
ignore_errors=None, include=None, omit=None, morfs=[],
show_missing=None, skip_covered=None, contexts=None, skip_empty=None, precision=None,
- sort=None,
+ sort=None, output_format=None,
)
_defaults.Coverage().xml_report(
ignore_errors=None, include=None, omit=None, morfs=[], outfile=None,
diff --git a/tests/test_summary.py b/tests/test_summary.py
index ac29f517..3e77285a 100644
--- a/tests/test_summary.py
+++ b/tests/test_summary.py
@@ -70,7 +70,6 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# mycode.py 4 0 100%
# -------------------------------
# TOTAL 4 0 100%
-
assert self.line_count(report) == 5
assert "/coverage/" not in report
assert "/tests/modules/covmod1.py " not in report
@@ -215,7 +214,6 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# mybranch.py 5 0 2 1 86%
# -----------------------------------------------
# TOTAL 5 0 2 1 86%
-
assert self.line_count(report) == 5
assert "mybranch.py " in report
assert self.last_line_squeezed(report) == "TOTAL 5 0 2 1 86%"
@@ -246,7 +244,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# --------------------------------------------
# mymissing.py 14 3 79% 3-4, 10
# --------------------------------------------
- # TOTAL 14 3 79% 3-4, 10
+ # TOTAL 14 3 79%
assert self.line_count(report) == 5
squeezed = self.squeezed_lines(report)
@@ -265,18 +263,6 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
cov = coverage.Coverage(branch=True)
self.start_import_stop(cov, "mybranch")
assert self.stdout() == 'x\ny\n'
- report = self.get_report(cov, show_missing=True)
-
- # Name Stmts Miss Branch BrPart Cover Missing
- # ----------------------------------------------------------
- # mybranch.py 6 0 4 2 80% 2->4, 4->exit
- # ----------------------------------------------------------
- # TOTAL 6 0 4 2 80%
-
- assert self.line_count(report) == 5
- squeezed = self.squeezed_lines(report)
- assert squeezed[2] == "mybranch.py 6 0 4 2 80% 2->4, 4->exit"
- assert squeezed[4] == "TOTAL 6 0 4 2 80%"
def test_report_show_missing_branches_and_lines(self):
self.make_file("main.py", """\
@@ -297,17 +283,6 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
cov = coverage.Coverage(branch=True)
self.start_import_stop(cov, "main")
assert self.stdout() == 'x\ny\n'
- report_lines = self.get_report(cov, squeeze=False, show_missing=True).splitlines()
-
- expected = [
- 'Name Stmts Miss Branch BrPart Cover Missing',
- '---------------------------------------------------------',
- 'main.py 1 0 0 0 100%',
- 'mybranch.py 10 2 8 3 61% 2->4, 4->6, 7-8',
- '---------------------------------------------------------',
- 'TOTAL 11 2 8 3 63%',
- ]
- assert expected == report_lines
def test_report_skip_covered_no_branches(self):
self.make_file("main.py", """
@@ -444,6 +419,26 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
assert self.line_count(report) == 6, report
squeezed = self.squeezed_lines(report)
assert squeezed[5] == "1 file skipped due to complete coverage."
+ report = self.get_report(cov, squeeze=False, skip_covered=True,
+ output_format="markdown")
+ # | Name | Stmts | Miss | Branch | BrPart | Cover |
+ # |---------- | -------: | -------: | -------: | -------: | -------: |
+ # | **TOTAL** | **3** | **0** | **0** | **0** | **100%** |
+ #
+ # 1 file skipped due to complete coverage.
+
+ assert self.line_count(report) == 5, report
+ assert report.split("\n")[0] == (
+ '| Name | Stmts | Miss | Branch | BrPart | Cover |'
+ )
+ assert report.split("\n")[1] == (
+ '|---------- | -------: | -------: | -------: | -------: | -------: |'
+ )
+ assert report.split("\n")[2] == (
+ '| **TOTAL** | **3** | **0** | **0** | **0** | **100%** |'
+ )
+ squeezed = self.squeezed_lines(report)
+ assert squeezed[4] == "1 file skipped due to complete coverage."
def test_report_skip_covered_longfilename(self):
self.make_file("long_______________filename.py", """
@@ -513,13 +508,14 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Cover
# ------------------------------------
+ # ------------------------------------
+ # TOTAL 0 0 100%
#
# 1 empty file skipped.
assert self.line_count(report) == 6, report
- squeezed = self.squeezed_lines(report)
- assert squeezed[3] == "TOTAL 0 0 100%"
- assert squeezed[5] == "1 empty file skipped."
+ assert report.split("\n")[3] == "TOTAL 0 0 100%"
+ assert report.split("\n")[5] == "1 empty file skipped."
def test_report_precision(self):
self.make_file(".coveragerc", """\
@@ -550,7 +546,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
cov = coverage.Coverage(branch=True)
self.start_import_stop(cov, "main")
assert self.stdout() == "n\nz\n"
- report = self.get_report(cov)
+ report = self.get_report(cov, squeeze=False)
# Name Stmts Miss Branch BrPart Cover
# ------------------------------------------------------
@@ -566,6 +562,29 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
assert squeezed[4] == "not_covered.py 4 0 2 1 83.333%"
assert squeezed[6] == "TOTAL 13 0 4 1 94.118%"
+ def test_report_precision_all_zero(self):
+ self.make_file("not_covered.py", """
+ def not_covered(n):
+ if n:
+ print("n")
+ """)
+ self.make_file("empty.py", "")
+ cov = coverage.Coverage(source=["."])
+ self.start_import_stop(cov, "empty")
+ report = self.get_report(cov, precision=6, squeeze=False)
+
+ # Name Stmts Miss Cover
+ # -----------------------------------------
+ # empty.py 0 0 100.000000%
+ # not_covered.py 3 3 0.000000%
+ # -----------------------------------------
+ # TOTAL 3 3 0.000000%
+
+ assert self.line_count(report) == 6, report
+ assert "empty.py 0 0 100.000000%" in report
+ assert "not_covered.py 3 3 0.000000%" in report
+ assert "TOTAL 3 3 0.000000%" in report
+
def test_dotpy_not_python(self):
# We run a .py file, and when reporting, we can't parse it as Python.
# We should get an error message in the report.
@@ -589,7 +608,6 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
"-----------------------------------\n" +
"TOTAL 1 0 100%\n"
)
-
cov = coverage.Coverage()
cov.load()
output = self.get_report(cov, squeeze=False)
@@ -666,6 +684,8 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
assert out == "Line One\nLine Two\nhello\n"
report = self.report_from_command("coverage report")
assert self.last_line_squeezed(report) == "TOTAL 5 0 100%"
+ report = self.report_from_command("coverage report --format=markdown")
+ assert self.last_line_squeezed(report) == "| **TOTAL** | **5** | **0** | **100%** |"
def test_bug_156_file_not_run_should_be_zero(self):
# https://github.com/nedbat/coveragepy/issues/156
@@ -695,7 +715,6 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
self.make_file(".coveragerc", "[run]\nsource = .\n")
report = self.run_TheCode_and_report_it()
-
assert "TheCode" in report
assert "thecode" not in report
@@ -743,6 +762,9 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
report = self.get_report(cov).splitlines()
assert "mod.py 1 0 100%" in report
+ report = self.get_report(cov, squeeze=False, output_format="markdown")
+ assert report.split("\n")[3] == "| mod.py | 1 | 0 | 100% |"
+ assert report.split("\n")[4] == "| **TOTAL** | **2** | **0** | **100%** |"
def test_missing_py_file_during_run(self):
# Create two Python files.
@@ -780,7 +802,44 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
report = self.get_report(cov)
assert "tests/modules/pkg1/__init__.py 1 0 0 0 100%" in report
assert "tests/modules/pkg2/__init__.py 0 0 0 0 100%" in report
+ report = self.get_report(cov, squeeze=False, output_format="markdown")
+ # get_report() escapes backslash so we expect forward slash escaped
+ # underscore
+ assert "tests/modules/pkg1//_/_init/_/_.py " in report
+ assert "| 1 | 0 | 0 | 0 | 100% |" in report
+ assert "tests/modules/pkg2//_/_init/_/_.py " in report
+ assert "| 0 | 0 | 0 | 0 | 100% |" in report
+
+ def test_markdown_with_missing(self):
+ self.make_file("mymissing.py", """\
+ def missing(x, y):
+ if x:
+ print("x")
+ return x
+ if y:
+ print("y")
+ try:
+ print("z")
+ 1/0
+ print("Never!")
+ except ZeroDivisionError:
+ pass
+ return x
+ missing(0, 1)
+ """)
+ cov = coverage.Coverage(source=["."])
+ self.start_import_stop(cov, "mymissing")
+ assert self.stdout() == 'y\nz\n'
+ report = self.get_report(cov,squeeze=False, output_format="markdown", show_missing=True)
+ # | Name | Stmts | Miss | Cover | Missing |
+ # |------------- | -------: | -------: | ------: | --------: |
+ # | mymissing.py | 14 | 3 | 79% | 3-4, 10 |
+ # | **TOTAL** | **14** | **3** | **79%** | |
+ assert self.line_count(report) == 4
+ report_lines = report.split("\n")
+ assert report_lines[2] == "| mymissing.py | 14 | 3 | 79% | 3-4, 10 |"
+ assert report_lines[3] == "| **TOTAL** | **14** | **3** | **79%** | |"
class ReportingReturnValueTest(CoverageTest):
"""Tests of reporting functions returning values."""
@@ -858,7 +917,6 @@ class SummaryReporterConfigurationTest(CoverageTest):
# about them are still valid. We want the three columns of numbers to
# sort in three different orders.
report = self.get_summary_text()
- print(report)
# Name Stmts Miss Cover
# ------------------------------
# file1.py 339 155 54%
@@ -866,7 +924,6 @@ class SummaryReporterConfigurationTest(CoverageTest):
# file10.py 234 228 3%
# ------------------------------
# TOTAL 586 386 34%
-
lines = report.splitlines()[2:-2]
assert len(lines) == 3
nums = [list(map(int, l.replace('%', '').split()[1:])) for l in lines]