diff options
Diffstat (limited to 'test/test_summary.py')
-rw-r--r-- | test/test_summary.py | 206 |
1 files changed, 171 insertions, 35 deletions
diff --git a/test/test_summary.py b/test/test_summary.py index fcc26125..b460c2dc 100644 --- a/test/test_summary.py +++ b/test/test_summary.py @@ -1,6 +1,6 @@ """Test text-based summary reporting for coverage.py""" -import os, re, sys, textwrap +import os, re, sys import coverage from coverage.backward import StringIO @@ -25,7 +25,7 @@ class SummaryTest(CoverageTest): def report_from_command(self, cmd): """Return the report from the `cmd`, with some convenience added.""" report = self.run_command(cmd).replace('\\', '/') - self.assertFalse("error" in report.lower()) + self.assertNotIn("error", report.lower()) return report def line_count(self, report): @@ -51,10 +51,10 @@ class SummaryTest(CoverageTest): # --------------------------------------------------------------------- # TOTAL 8 0 100% - self.assertFalse("/coverage/__init__/" in report) - self.assertTrue("/test/modules/covmod1 " in report) - self.assertTrue("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/__init__/", report) + self.assertIn("/test/modules/covmod1 ", report) + self.assertIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "TOTAL 8 0 100%") def test_report_just_one(self): @@ -67,10 +67,10 @@ class SummaryTest(CoverageTest): # mycode 4 0 100% self.assertEqual(self.line_count(report), 3) - self.assertFalse("/coverage/" in report) - self.assertFalse("/test/modules/covmod1 " in report) - self.assertFalse("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/", report) + self.assertNotIn("/test/modules/covmod1 ", report) + self.assertNotIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "mycode 4 0 100%") def test_report_omitting(self): @@ -84,10 +84,10 @@ class SummaryTest(CoverageTest): # mycode 4 0 100% self.assertEqual(self.line_count(report), 3) - self.assertFalse("/coverage/" in report) - self.assertFalse("/test/modules/covmod1 " in report) - self.assertFalse("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/", report) + self.assertNotIn("/test/modules/covmod1 ", report) + self.assertNotIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "mycode 4 0 100%") def test_report_including(self): @@ -100,10 +100,10 @@ class SummaryTest(CoverageTest): # mycode 4 0 100% self.assertEqual(self.line_count(report), 3) - self.assertFalse("/coverage/" in report) - self.assertFalse("/test/modules/covmod1 " in report) - self.assertFalse("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/", report) + self.assertNotIn("/test/modules/covmod1 ", report) + self.assertNotIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "mycode 4 0 100%") def test_report_branches(self): @@ -118,15 +118,120 @@ class SummaryTest(CoverageTest): self.assertEqual(out, 'x\n') report = self.report_from_command("coverage report") - # Name Stmts Miss Branch BrPart Cover + # Name Stmts Miss Branch BrMiss Cover # -------------------------------------------- # mybranch 5 0 2 1 85% self.assertEqual(self.line_count(report), 3) - self.assertTrue("mybranch " in report) + self.assertIn("mybranch ", report) self.assertEqual(self.last_line_squeezed(report), "mybranch 5 0 2 1 86%") + 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. + + self.run_command("coverage run mycode.py") + self.make_file("mycode.py", "This isn't python at all!") + report = self.report_from_command("coverage -r mycode.py") + + # pylint: disable=C0301 + # Name Stmts Miss Cover + # ---------------------------- + # mycode NotPython: Couldn't parse '/tmp/test_cover/63354509363/mycode.py' as Python source: 'invalid syntax' at line 1 + + last = self.last_line_squeezed(report) + # The actual file name varies run to run. + last = re.sub(r"parse '.*mycode.py", "parse 'mycode.py", last) + # The actual error message varies version to version + last = re.sub(r": '.*' at", ": 'error' at", last) + self.assertEqual(last, + "mycode NotPython: " + "Couldn't parse 'mycode.py' as Python source: " + "'error' at line 1" + ) + + def test_dotpy_not_python_ignored(self): + # We run a .py file, and when reporting, we can't parse it as Python, + # but we've said to ignore errors, so there's no error reported. + self.run_command("coverage run mycode.py") + self.make_file("mycode.py", "This isn't python at all!") + report = self.report_from_command("coverage -r -i mycode.py") + + # Name Stmts Miss Cover + # ---------------------------- + + self.assertEqual(self.line_count(report), 2) + + def test_dothtml_not_python(self): + # We run a .html file, and when reporting, we can't parse it as + # Python. Since it wasn't .py, no error is reported. + + # Run an "html" file + self.make_file("mycode.html", "a = 1") + self.run_command("coverage run mycode.html") + # Before reporting, change it to be an HTML file. + self.make_file("mycode.html", "<h1>This isn't python at all!</h1>") + report = self.report_from_command("coverage -r mycode.html") + + # Name Stmts Miss Cover + # ---------------------------- + + self.assertEqual(self.line_count(report), 2) + + def get_report(self, cov): + """Get the report from `cov`, and canonicalize it.""" + repout = StringIO() + cov.report(file=repout, show_missing=False) + report = repout.getvalue().replace('\\', '/') + report = re.sub(r" +", " ", report) + return report + + def test_bug_156_file_not_run_should_be_zero(self): + # https://bitbucket.org/ned/coveragepy/issue/156 + self.make_file("mybranch.py", """\ + def branch(x): + if x: + print("x") + return x + branch(1) + """) + self.make_file("main.py", """\ + print("y") + """) + cov = coverage.coverage(branch=True, source=["."]) + cov.start() + import main # pylint: disable=F0401,W0612 + cov.stop() + report = self.get_report(cov).splitlines() + self.assertIn("mybranch 5 5 2 2 0%", report) + + def run_TheCode_and_report_it(self): + """A helper for the next few tests.""" + cov = coverage.coverage() + cov.start() + import TheCode # pylint: disable=F0401,W0612 + cov.stop() + return self.get_report(cov) + + def test_bug_203_mixed_case_listed_twice_with_rc(self): + self.make_file("TheCode.py", "a = 1\n") + self.make_file(".coveragerc", "[run]\nsource = .\n") + + report = self.run_TheCode_and_report_it() + + self.assertIn("TheCode", report) + self.assertNotIn("thecode", report) + + def test_bug_203_mixed_case_listed_twice(self): + self.make_file("TheCode.py", "a = 1\n") + + report = self.run_TheCode_and_report_it() + + self.assertIn("TheCode", report) + self.assertNotIn("thecode", report) + + class SummaryTest2(CoverageTest): """Another bunch of summary tests.""" # This class exists because tests naturally clump into classes based on the @@ -138,28 +243,59 @@ class SummaryTest2(CoverageTest): def setUp(self): super(SummaryTest2, self).setUp() # Parent class saves and restores sys.path, we can just modify it. - sys.path.append(self.nice_file(os.path.dirname(__file__), 'modules')) + this_dir = os.path.dirname(__file__) + sys.path.append(self.nice_file(this_dir, 'modules')) + sys.path.append(self.nice_file(this_dir, 'moremodules')) def test_empty_files(self): + # Shows that empty files like __init__.py are listed as having zero + # statements, not one statement. cov = coverage.coverage() cov.start() - import usepkgs # pylint: disable-msg=F0401,W0612 + import usepkgs # pylint: disable=F0401,W0612 cov.stop() repout = StringIO() cov.report(file=repout, show_missing=False) report = repout.getvalue().replace('\\', '/') - self.assertMultiLineEqual(report, textwrap.dedent("""\ - Name Stmts Miss Cover - ------------------------------------------------ - test/modules/pkg1/__init__ 1 0 100% - test/modules/pkg1/p1a 3 0 100% - test/modules/pkg1/p1b 3 0 100% - test/modules/pkg2/__init__ 0 0 100% - test/modules/pkg2/p2a 3 0 100% - test/modules/pkg2/p2b 3 0 100% - test/modules/usepkgs 2 0 100% - ------------------------------------------------ - TOTAL 15 0 100% - """)) + report = re.sub(r"\s+", " ", report) + self.assertIn("test/modules/pkg1/__init__ 1 0 100%", report) + self.assertIn("test/modules/pkg2/__init__ 0 0 100%", report) + + +class ReportingReturnValue(CoverageTest): + """Tests of reporting functions returning values.""" + + def run_coverage(self): + """Run coverage on doit.py and return the coverage object.""" + self.make_file("doit.py", """\ + a = 1 + b = 2 + c = 3 + d = 4 + if a > 10: + f = 6 + g = 7 + """) + + cov = coverage.coverage() + cov.start() + self.import_local_file("doit") + cov.stop() + return cov + + def test_report(self): + cov = self.run_coverage() + val = cov.report(include="*/doit.py") + self.assertAlmostEqual(val, 85.7, 1) + + def test_html(self): + cov = self.run_coverage() + val = cov.html_report(include="*/doit.py") + self.assertAlmostEqual(val, 85.7, 1) + + def test_xml(self): + cov = self.run_coverage() + val = cov.xml_report(include="*/doit.py") + self.assertAlmostEqual(val, 85.7, 1) |