# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt """Test text-based summary reporting for coverage.py""" import glob import os import os.path import py_compile import re import sys import coverage from coverage import env from coverage.backward import StringIO from tests.coveragetest import CoverageTest HERE = os.path.dirname(__file__) class SummaryTest(CoverageTest): """Tests of the text summary reporting for coverage.py.""" def setUp(self): super(SummaryTest, self).setUp() # Parent class saves and restores sys.path, we can just modify it. sys.path.append(self.nice_file(HERE, 'modules')) def make_mycode(self): """Make the mycode.py file when needed.""" self.make_file("mycode.py", """\ import covmod1 import covmodzip1 a = 1 print('done') """) def test_report(self): self.make_mycode() out = self.run_command("coverage run mycode.py") self.assertEqual(out, 'done\n') report = self.report_from_command("coverage report") # Name Stmts Miss Cover # ------------------------------------------------------------------ # c:/ned/coverage/tests/modules/covmod1.py 2 0 100% # c:/ned/coverage/tests/zipmods.zip/covmodzip1.py 3 0 100% # mycode.py 4 0 100% # ------------------------------------------------------------------ # TOTAL 9 0 100% self.assertNotIn("/coverage/__init__/", report) self.assertIn("/tests/modules/covmod1.py ", report) self.assertIn("/tests/zipmods.zip/covmodzip1.py ", report) self.assertIn("mycode.py ", report) self.assertEqual(self.last_line_squeezed(report), "TOTAL 9 0 100%") def test_report_just_one(self): # Try reporting just one module self.make_mycode() self.run_command("coverage run mycode.py") report = self.report_from_command("coverage report mycode.py") # Name Stmts Miss Cover # ------------------------------- # mycode.py 4 0 100% self.assertEqual(self.line_count(report), 3) 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%") def test_report_wildcard(self): # Try reporting using wildcards to get the modules. self.make_mycode() self.run_command("coverage run mycode.py") report = self.report_from_command("coverage report my*.py") # Name Stmts Miss Cover # ------------------------------- # mycode.py 4 0 100% self.assertEqual(self.line_count(report), 3) 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%") def test_report_omitting(self): # Try reporting while omitting some modules self.make_mycode() self.run_command("coverage run mycode.py") report = self.report_from_command("coverage report --omit '%s/*'" % HERE) # Name Stmts Miss Cover # ------------------------------- # mycode.py 4 0 100% self.assertEqual(self.line_count(report), 3) 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%") def test_report_including(self): # Try reporting while including some modules self.make_mycode() self.run_command("coverage run mycode.py") report = self.report_from_command("coverage report --include=mycode*") # Name Stmts Miss Cover # ------------------------------- # mycode.py 4 0 100% self.assertEqual(self.line_count(report), 3) 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%") def test_report_branches(self): self.make_file("mybranch.py", """\ def branch(x): if x: print("x") return x branch(1) """) out = self.run_command("coverage run --branch mybranch.py") self.assertEqual(out, 'x\n') report = self.report_from_command("coverage report") # Name Stmts Miss Branch BrPart Cover # ----------------------------------------------- # mybranch.py 5 0 2 1 85% self.assertEqual(self.line_count(report), 3) self.assertIn("mybranch.py ", report) self.assertEqual(self.last_line_squeezed(report), "mybranch.py 5 0 2 1 86%") def test_report_show_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) """) out = self.run_command("coverage run mymissing.py") self.assertEqual(out, 'y\nz\n') report = self.report_from_command("coverage report --show-missing") # Name Stmts Miss Cover Missing # -------------------------------------------- # mymissing.py 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") def test_report_show_missing_branches(self): self.make_file("mybranch.py", """\ def branch(x, y): if x: print("x") if y: print("y") return x branch(1, 1) """) out = self.run_command("coverage run --branch mybranch.py") self.assertEqual(out, 'x\ny\n') report = self.report_from_command("coverage report --show-missing") # Name Stmts Miss Branch BrPart Cover Missing # ---------------------------------------------------------- # mybranch.py 7 0 4 2 82% 2->4, 4->6 self.assertEqual(self.line_count(report), 3) self.assertIn("mybranch.py ", report) self.assertEqual(self.last_line_squeezed(report), "mybranch.py 7 0 4 2 82% 2->4, 4->6") def test_report_show_missing_branches_and_lines(self): self.make_file("main.py", """\ import mybranch """) self.make_file("mybranch.py", """\ def branch(x, y, z): if x: print("x") if y: print("y") if z: if x and y: print("z") return x branch(1, 1, 0) """) out = self.run_command("coverage run --branch main.py") self.assertEqual(out, 'x\ny\n') report = self.report_from_command("coverage report --show-missing") # Name Stmts Miss Branch BrPart Cover Missing # ------------------------------------------------------- # main.py 1 0 0 0 100% # mybranch.py 10 2 8 3 61% 7-8, 2->4, 4->6, 6->7 # ------------------------------------------------------- # TOTAL 11 2 8 3 63% self.assertEqual(self.line_count(report), 6) squeezed = self.squeezed_lines(report) self.assertEqual( squeezed[2], "main.py 1 0 0 0 100%" ) self.assertEqual( squeezed[3], "mybranch.py 10 2 8 3 61% 7-8, 2->4, 4->6, 6->7" ) self.assertEqual( squeezed[5], "TOTAL 11 2 8 3 63%" ) def test_report_skip_covered_no_branches(self): self.make_file("main.py", """ import not_covered def normal(): print("z") normal() """) self.make_file("not_covered.py", """ def not_covered(): print("n") """) out = self.run_command("coverage run main.py") self.assertEqual(out, "z\n") report = self.report_from_command("coverage report --skip-covered --fail-under=70") # Name Stmts Miss Cover # ------------------------------------ # not_covered.py 2 1 50% # ------------------------------------ # TOTAL 6 1 83% # # 1 file skipped due to complete coverage. self.assertEqual(self.line_count(report), 7, report) squeezed = self.squeezed_lines(report) self.assertEqual(squeezed[2], "not_covered.py 2 1 50%") self.assertEqual(squeezed[4], "TOTAL 6 1 83%") self.assertEqual(squeezed[6], "1 file skipped due to complete coverage.") self.assertEqual(self.last_command_status, 0) def test_report_skip_covered_branches(self): self.make_file("main.py", """ import not_covered, covered def normal(z): if z: print("z") normal(True) normal(False) """) self.make_file("not_covered.py", """ def not_covered(n): if n: print("n") not_covered(True) """) self.make_file("covered.py", """ def foo(): pass foo() """) out = self.run_command("coverage run --branch main.py") self.assertEqual(out, "n\nz\n") report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover # -------------------------------------------------- # not_covered.py 4 0 2 1 83% # -------------------------------------------------- # TOTAL 13 0 4 1 94% # # 2 files skipped due to complete coverage. self.assertEqual(self.line_count(report), 7, report) squeezed = self.squeezed_lines(report) self.assertEqual(squeezed[2], "not_covered.py 4 0 2 1 83%") self.assertEqual(squeezed[4], "TOTAL 13 0 4 1 94%") self.assertEqual(squeezed[6], "2 files skipped due to complete coverage.") def test_report_skip_covered_branches_with_totals(self): self.make_file("main.py", """ import not_covered import also_not_run def normal(z): if z: print("z") normal(True) normal(False) """) self.make_file("not_covered.py", """ def not_covered(n): if n: print("n") not_covered(True) """) self.make_file("also_not_run.py", """ def does_not_appear_in_this_film(ni): print("Ni!") """) out = self.run_command("coverage run --branch main.py") self.assertEqual(out, "n\nz\n") report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover # -------------------------------------------------- # also_not_run.py 2 1 0 0 50% # not_covered.py 4 0 2 1 83% # -------------------------------------------------- # TOTAL 13 1 4 1 88% # # 1 file skipped due to complete coverage. self.assertEqual(self.line_count(report), 8, report) squeezed = self.squeezed_lines(report) self.assertEqual(squeezed[2], "also_not_run.py 2 1 0 0 50%") self.assertEqual(squeezed[3], "not_covered.py 4 0 2 1 83%") self.assertEqual(squeezed[5], "TOTAL 13 1 4 1 88%") self.assertEqual(squeezed[7], "1 file skipped due to complete coverage.") def test_report_skip_covered_all_files_covered(self): self.make_file("main.py", """ def foo(): pass foo() """) out = self.run_command("coverage run --branch main.py") self.assertEqual(out, "") report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover # ------------------------------------------- # # 1 file skipped due to complete coverage. self.assertEqual(self.line_count(report), 4, report) squeezed = self.squeezed_lines(report) self.assertEqual(squeezed[3], "1 file skipped due to complete coverage.") def test_report_skip_covered_no_data(self): report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover # ------------------------------------------- # No data to report. self.assertEqual(self.line_count(report), 3, report) squeezed = self.squeezed_lines(report) self.assertEqual(squeezed[2], "No data to 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. self.make_mycode() self.run_command("coverage run mycode.py") self.make_file("mycode.py", "This isn't python at all!") report = self.report_from_command("coverage report mycode.py") # Name Stmts Miss Cover # ---------------------------- # mycode NotPython: Couldn't parse '...' as Python source: 'invalid syntax' at line 1 # No data to report. last = self.squeezed_lines(report)[-2] # 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.py 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.make_mycode() self.run_command("coverage run mycode.py") self.make_file("mycode.py", "This isn't python at all!") report = self.report_from_command("coverage report -i mycode.py") # Name Stmts Miss Cover # ---------------------------- self.assertEqual(self.line_count(report), 3) self.assertIn('No data to report.', report) 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", "