summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJudson Neer <judson.neer@gmail.com>2021-01-05 08:53:19 -0800
committerNed Batchelder <ned@nedbatchelder.com>2021-01-06 13:50:13 -0500
commit051bdf23b5d86a15ada43523c00f8f3462063ad6 (patch)
tree5a726432bb9793a1fef67bb827402667c6ff5763
parent7ff93a9740da5dec4eba6c6cad288d25a472d75a (diff)
downloadpython-coveragepy-git-051bdf23b5d86a15ada43523c00f8f3462063ad6.tar.gz
Always output TOTAL line.
-rw-r--r--CHANGES.rst5
-rw-r--r--CONTRIBUTORS.txt1
-rw-r--r--coverage/summary.py4
-rw-r--r--tests/test_api.py12
-rw-r--r--tests/test_concurrency.py4
-rw-r--r--tests/test_plugins.py2
-rw-r--r--tests/test_process.py12
-rw-r--r--tests/test_summary.py73
8 files changed, 76 insertions, 37 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 2f6214c4..2e68f6b9 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -24,8 +24,9 @@ want to know what's different in 5.0 since 4.5.x, see :ref:`whatsnew5x`.
Unreleased
----------
-Nothing yet.
-
+- The text report produced by ``coverage report`` now always outputs a TOTAL
+ line, even if only one Python file is reported. This makes regex parsing
+ of the output easier. Thanks, Judson Neer.
.. _changes_531:
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 3e52e45e..44b4f557 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -79,6 +79,7 @@ Jon Chappell
Jon Dufresne
Joseph Tate
Josh Williams
+Judson Neer
Julian Berman
Julien Voisin
Justas Sadzevičius
diff --git a/coverage/summary.py b/coverage/summary.py
index 986cd2f2..0c7fa551 100644
--- a/coverage/summary.py
+++ b/coverage/summary.py
@@ -120,8 +120,8 @@ class SummaryReporter(object):
for line in lines:
self.writeout(line[0])
- # Write a TOTAl line if we had more than one file.
- if self.total.n_files > 1:
+ # 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:
diff --git a/tests/test_api.py b/tests/test_api.py
index 3552f8f4..f8b7b4b2 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -306,9 +306,11 @@ class ApiTest(CoverageTest):
# Name Stmts Miss Cover
# --------------------------------
# foo/bar.py 1 1 0%
+ # --------------------------------
+ # TOTAL 1 1 0%
- last = self.last_line_squeezed(self.stdout()).replace("\\", "/")
- self.assertEqual("foo/bar.py 1 1 0%", last)
+ last = self.last_line_squeezed(self.stdout())
+ self.assertEqual("TOTAL 1 1 0%", last)
def test_cov4_data_file(self):
cov4_data = (
@@ -587,6 +589,8 @@ class ApiTest(CoverageTest):
Name Stmts Miss Cover
---------------------------
b.py 1 0 100%
+ ---------------------------
+ TOTAL 1 0 100%
""")
self.assertEqual(expected, self.stdout())
@@ -1049,6 +1053,8 @@ class TestRunnerPluginTest(CoverageTest):
Name Stmts Miss Cover Missing
--------------------------------------------
no_biggie.py 4 1 75% 4
+ --------------------------------------------
+ TOTAL 4 1 75%
"""))
if cd:
os.chdir("..")
@@ -1092,6 +1098,8 @@ class TestRunnerPluginTest(CoverageTest):
Name Stmts Miss Cover
-----------------------------
prog.py 4 1 75%
+ -----------------------------
+ TOTAL 4 1 75%
"""))
self.assert_file_count(".coverage", 0)
self.assert_file_count(".coverage.*", 1)
diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py
index 7109f170..2469e296 100644
--- a/tests/test_concurrency.py
+++ b/tests/test_concurrency.py
@@ -409,7 +409,7 @@ class MultiprocessingTest(CoverageTest):
out = self.run_command("coverage report -m")
last_line = self.squeezed_lines(out)[-1]
- self.assertRegex(last_line, r"multi.py \d+ 0 100%")
+ self.assertRegex(last_line, r"TOTAL \d+ 0 100%")
def test_multiprocessing_simple(self):
nprocs = 3
@@ -466,7 +466,7 @@ class MultiprocessingTest(CoverageTest):
out = self.run_command("coverage report -m")
last_line = self.squeezed_lines(out)[-1]
- self.assertRegex(last_line, r"multi.py \d+ 0 \d+ 0 100%")
+ self.assertRegex(last_line, r"TOTAL \d+ 0 \d+ 0 100%")
def test_multiprocessing_with_branching(self):
nprocs = 3
diff --git a/tests/test_plugins.py b/tests/test_plugins.py
index 1f224695..813d370e 100644
--- a/tests/test_plugins.py
+++ b/tests/test_plugins.py
@@ -522,6 +522,8 @@ class GoodFileTracerTest(FileTracerTest):
'Name Stmts Miss Cover Missing',
'-----------------------------------------------',
'unsuspecting.py 6 3 50% 2, 4, 6',
+ '-----------------------------------------------',
+ 'TOTAL 6 3 50%',
]
self.assertEqual(expected, report)
self.assertEqual(total, 50)
diff --git a/tests/test_process.py b/tests/test_process.py
index 52255ac2..9fb930de 100644
--- a/tests/test_process.py
+++ b/tests/test_process.py
@@ -341,6 +341,8 @@ class ProcessTest(CoverageTest):
Name Stmts Miss Cover
-------------------------------
b_or_c.py 8 0 100%
+ -------------------------------
+ TOTAL 8 0 100%
"""))
def test_combine_with_aliases(self):
@@ -1231,7 +1233,7 @@ class FailUnderTest(CoverageTest):
def test_report_43_is_ok(self):
st, out = self.run_command_status("coverage report --fail-under=43")
self.assertEqual(st, 0)
- self.assertEqual(self.last_line_squeezed(out), "forty_two_plus.py 7 4 43%")
+ self.assertEqual(self.last_line_squeezed(out), "TOTAL 7 4 43%")
def test_report_43_is_not_ok(self):
st, out = self.run_command_status("coverage report --fail-under=44")
@@ -1305,6 +1307,8 @@ class UnicodeFilePathsTest(CoverageTest):
u"Name Stmts Miss Cover\n"
u"----------------------------\n"
u"h\xe2t.py 1 0 100%\n"
+ u"----------------------------\n"
+ u"TOTAL 1 0 100%\n"
)
if env.PY2:
@@ -1348,8 +1352,10 @@ class UnicodeFilePathsTest(CoverageTest):
report_expected = (
u"Name Stmts Miss Cover\n"
u"-----------------------------------\n"
- u"\xe2%saccented.py 1 0 100%%\n" % os.sep
- )
+ u"\xe2%saccented.py 1 0 100%%\n"
+ u"-----------------------------------\n"
+ u"TOTAL 1 0 100%%\n"
+ ) % os.sep
if env.PY2:
report_expected = report_expected.encode(output_encoding())
diff --git a/tests/test_summary.py b/tests/test_summary.py
index eb25a4d8..feaa0fe0 100644
--- a/tests/test_summary.py
+++ b/tests/test_summary.py
@@ -70,13 +70,15 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Cover
# -------------------------------
# mycode.py 4 0 100%
+ # -------------------------------
+ # TOTAL 4 0 100%
- self.assertEqual(self.line_count(report), 3)
+ self.assertEqual(self.line_count(report), 5)
self.assertNotIn("/coverage/", report)
self.assertNotIn("/tests/modules/covmod1.py ", report)
self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
self.assertIn("mycode.py ", report)
- self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
+ self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%")
def test_report_wildcard(self):
# Try reporting using wildcards to get the modules.
@@ -87,13 +89,15 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Cover
# -------------------------------
# mycode.py 4 0 100%
+ # -------------------------------
+ # TOTAL 4 0 100%
- self.assertEqual(self.line_count(report), 3)
+ self.assertEqual(self.line_count(report), 5)
self.assertNotIn("/coverage/", report)
self.assertNotIn("/tests/modules/covmod1.py ", report)
self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
self.assertIn("mycode.py ", report)
- self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
+ self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%")
def test_report_omitting(self):
# Try reporting while omitting some modules
@@ -105,13 +109,15 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Cover
# -------------------------------
# mycode.py 4 0 100%
+ # -------------------------------
+ # TOTAL 4 0 100%
- self.assertEqual(self.line_count(report), 3)
+ self.assertEqual(self.line_count(report), 5)
self.assertNotIn("/coverage/", report)
self.assertNotIn("/tests/modules/covmod1.py ", report)
self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
self.assertIn("mycode.py ", report)
- self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
+ self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%")
def test_report_including(self):
# Try reporting while including some modules
@@ -122,13 +128,15 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Cover
# -------------------------------
# mycode.py 4 0 100%
+ # -------------------------------
+ # TOTAL 4 0 100%
- self.assertEqual(self.line_count(report), 3)
+ self.assertEqual(self.line_count(report), 5)
self.assertNotIn("/coverage/", report)
self.assertNotIn("/tests/modules/covmod1.py ", report)
self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
self.assertIn("mycode.py ", report)
- self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
+ self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%")
def test_run_source_vs_report_include(self):
# https://github.com/nedbat/coveragepy/issues/621
@@ -179,11 +187,13 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Branch BrPart Cover
# -----------------------------------------------
- # mybranch.py 5 0 2 1 85%
+ # mybranch.py 5 0 2 1 86%
+ # -----------------------------------------------
+ # TOTAL 5 0 2 1 86%
- self.assertEqual(self.line_count(report), 3)
+ self.assertEqual(self.line_count(report), 5)
self.assertIn("mybranch.py ", report)
- self.assertEqual(self.last_line_squeezed(report), "mybranch.py 5 0 2 1 86%")
+ self.assertEqual(self.last_line_squeezed(report), "TOTAL 5 0 2 1 86%")
def test_report_show_missing(self):
self.make_file("mymissing.py", """\
@@ -209,10 +219,13 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Cover Missing
# --------------------------------------------
# mymissing.py 14 3 79% 3-4, 10
+ # --------------------------------------------
+ # TOTAL 14 3 79% 3-4, 10
- self.assertEqual(self.line_count(report), 3)
- self.assertIn("mymissing.py ", report)
- self.assertEqual(self.last_line_squeezed(report), "mymissing.py 14 3 79% 3-4, 10")
+ self.assertEqual(self.line_count(report), 5)
+ squeezed = self.squeezed_lines(report)
+ self.assertEqual(squeezed[2], "mymissing.py 14 3 79% 3-4, 10")
+ self.assertEqual(squeezed[4], "TOTAL 14 3 79%")
def test_report_show_missing_branches(self):
self.make_file("mybranch.py", """\
@@ -231,10 +244,13 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Branch BrPart Cover Missing
# ----------------------------------------------------------
# mybranch.py 6 0 4 2 80% 2->4, 4->exit
+ # ----------------------------------------------------------
+ # TOTAL 6 0 4 2 80%
- self.assertEqual(self.line_count(report), 3)
- self.assertIn("mybranch.py ", report)
- self.assertEqual(self.last_line_squeezed(report), "mybranch.py 6 0 4 2 80% 2->4, 4->exit")
+ self.assertEqual(self.line_count(report), 5)
+ squeezed = self.squeezed_lines(report)
+ self.assertEqual(squeezed[2], "mybranch.py 6 0 4 2 80% 2->4, 4->exit")
+ self.assertEqual(squeezed[4], "TOTAL 6 0 4 2 80%")
def test_report_show_missing_branches_and_lines(self):
self.make_file("main.py", """\
@@ -394,12 +410,14 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Branch BrPart Cover
# -------------------------------------------
+ # -----------------------------------------
+ # TOTAL 3 0 0 0 100%
#
# 1 file skipped due to complete coverage.
- self.assertEqual(self.line_count(report), 4, report)
+ self.assertEqual(self.line_count(report), 6, report)
squeezed = self.squeezed_lines(report)
- self.assertEqual(squeezed[3], "1 file skipped due to complete coverage.")
+ self.assertEqual(squeezed[5], "1 file skipped due to complete coverage.")
def test_report_skip_covered_longfilename(self):
self.make_file("long_______________filename.py", """
@@ -413,14 +431,16 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Name Stmts Miss Branch BrPart Cover
# -----------------------------------------
+ # -----------------------------------------
+ # TOTAL 3 0 0 0 100%
#
# 1 file skipped due to complete coverage.
- self.assertEqual(self.line_count(report), 4, report)
+ self.assertEqual(self.line_count(report), 6, report)
lines = self.report_lines(report)
self.assertEqual(lines[0], "Name Stmts Miss Branch BrPart Cover")
squeezed = self.squeezed_lines(report)
- self.assertEqual(squeezed[3], "1 file skipped due to complete coverage.")
+ self.assertEqual(squeezed[5], "1 file skipped due to complete coverage.")
def test_report_skip_covered_no_data(self):
report = self.report_from_command("coverage report --skip-covered")
@@ -472,9 +492,10 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
#
# 1 empty file skipped.
- self.assertEqual(self.line_count(report), 4, report)
- lines = self.report_lines(report)
- self.assertEqual(lines[3], "1 empty file skipped.")
+ self.assertEqual(self.line_count(report), 6, report)
+ squeezed = self.squeezed_lines(report)
+ self.assertEqual(squeezed[3], "TOTAL 0 0 100%")
+ self.assertEqual(squeezed[5], "1 empty file skipped.")
def test_report_precision(self):
self.make_file(".coveragerc", """\
@@ -621,7 +642,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
out = self.run_command("coverage run --source=. xxx")
self.assertEqual(out, "xxx: 3 4 0 7\n")
report = self.report_from_command("coverage report")
- self.assertEqual(self.last_line_squeezed(report), "xxx 7 1 86%")
+ self.assertEqual(self.last_line_squeezed(report), "TOTAL 7 1 86%")
def test_report_with_chdir(self):
self.make_file("chdir.py", """\
@@ -635,7 +656,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
out = self.run_command("coverage run --source=. chdir.py")
self.assertEqual(out, "Line One\nLine Two\nhello\n")
report = self.report_from_command("coverage report")
- self.assertEqual(self.last_line_squeezed(report), "chdir.py 5 0 100%")
+ self.assertEqual(self.last_line_squeezed(report), "TOTAL 5 0 100%")
def get_report(self, cov):
"""Get the report from `cov`, and canonicalize it."""