Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: tools/telemetry/third_party/coverage/tests/test_summary.py

Issue 1366913004: Add coverage Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
3
4 """Test text-based summary reporting for coverage.py"""
5
6 import glob
7 import os
8 import os.path
9 import py_compile
10 import re
11 import sys
12
13 import coverage
14 from coverage import env
15 from coverage.backward import StringIO
16
17 from tests.coveragetest import CoverageTest
18
19 HERE = os.path.dirname(__file__)
20
21
22 class SummaryTest(CoverageTest):
23 """Tests of the text summary reporting for coverage.py."""
24
25 def setUp(self):
26 super(SummaryTest, self).setUp()
27 # Parent class saves and restores sys.path, we can just modify it.
28 sys.path.append(self.nice_file(HERE, 'modules'))
29
30 def make_mycode(self):
31 """Make the mycode.py file when needed."""
32 self.make_file("mycode.py", """\
33 import covmod1
34 import covmodzip1
35 a = 1
36 print('done')
37 """)
38
39 def test_report(self):
40 self.make_mycode()
41 out = self.run_command("coverage run mycode.py")
42 self.assertEqual(out, 'done\n')
43 report = self.report_from_command("coverage report")
44
45 # Name Stmts Miss Cover
46 # ------------------------------------------------------------------
47 # c:/ned/coverage/tests/modules/covmod1.py 2 0 100%
48 # c:/ned/coverage/tests/zipmods.zip/covmodzip1.py 3 0 100%
49 # mycode.py 4 0 100%
50 # ------------------------------------------------------------------
51 # TOTAL 9 0 100%
52
53 self.assertNotIn("/coverage/__init__/", report)
54 self.assertIn("/tests/modules/covmod1.py ", report)
55 self.assertIn("/tests/zipmods.zip/covmodzip1.py ", report)
56 self.assertIn("mycode.py ", report)
57 self.assertEqual(self.last_line_squeezed(report), "TOTAL 9 0 100%")
58
59 def test_report_just_one(self):
60 # Try reporting just one module
61 self.make_mycode()
62 self.run_command("coverage run mycode.py")
63 report = self.report_from_command("coverage report mycode.py")
64
65 # Name Stmts Miss Cover
66 # -------------------------------
67 # mycode.py 4 0 100%
68
69 self.assertEqual(self.line_count(report), 3)
70 self.assertNotIn("/coverage/", report)
71 self.assertNotIn("/tests/modules/covmod1.py ", report)
72 self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
73 self.assertIn("mycode.py ", report)
74 self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
75
76 def test_report_wildcard(self):
77 # Try reporting using wildcards to get the modules.
78 self.make_mycode()
79 self.run_command("coverage run mycode.py")
80 report = self.report_from_command("coverage report my*.py")
81
82 # Name Stmts Miss Cover
83 # -------------------------------
84 # mycode.py 4 0 100%
85
86 self.assertEqual(self.line_count(report), 3)
87 self.assertNotIn("/coverage/", report)
88 self.assertNotIn("/tests/modules/covmod1.py ", report)
89 self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
90 self.assertIn("mycode.py ", report)
91 self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
92
93 def test_report_omitting(self):
94 # Try reporting while omitting some modules
95 self.make_mycode()
96 self.run_command("coverage run mycode.py")
97 report = self.report_from_command("coverage report --omit '%s/*'" % HERE )
98
99 # Name Stmts Miss Cover
100 # -------------------------------
101 # mycode.py 4 0 100%
102
103 self.assertEqual(self.line_count(report), 3)
104 self.assertNotIn("/coverage/", report)
105 self.assertNotIn("/tests/modules/covmod1.py ", report)
106 self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
107 self.assertIn("mycode.py ", report)
108 self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
109
110 def test_report_including(self):
111 # Try reporting while including some modules
112 self.make_mycode()
113 self.run_command("coverage run mycode.py")
114 report = self.report_from_command("coverage report --include=mycode*")
115
116 # Name Stmts Miss Cover
117 # -------------------------------
118 # mycode.py 4 0 100%
119
120 self.assertEqual(self.line_count(report), 3)
121 self.assertNotIn("/coverage/", report)
122 self.assertNotIn("/tests/modules/covmod1.py ", report)
123 self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report)
124 self.assertIn("mycode.py ", report)
125 self.assertEqual(self.last_line_squeezed(report), "mycode.py 4 0 100%")
126
127 def test_report_branches(self):
128 self.make_file("mybranch.py", """\
129 def branch(x):
130 if x:
131 print("x")
132 return x
133 branch(1)
134 """)
135 out = self.run_command("coverage run --branch mybranch.py")
136 self.assertEqual(out, 'x\n')
137 report = self.report_from_command("coverage report")
138
139 # Name Stmts Miss Branch BrPart Cover
140 # -----------------------------------------------
141 # mybranch.py 5 0 2 1 85%
142
143 self.assertEqual(self.line_count(report), 3)
144 self.assertIn("mybranch.py ", report)
145 self.assertEqual(self.last_line_squeezed(report), "mybranch.py 5 0 2 1 8 6%")
146
147 def test_report_show_missing(self):
148 self.make_file("mymissing.py", """\
149 def missing(x, y):
150 if x:
151 print("x")
152 return x
153 if y:
154 print("y")
155 try:
156 print("z")
157 1/0
158 print("Never!")
159 except ZeroDivisionError:
160 pass
161 return x
162 missing(0, 1)
163 """)
164 out = self.run_command("coverage run mymissing.py")
165 self.assertEqual(out, 'y\nz\n')
166 report = self.report_from_command("coverage report --show-missing")
167
168 # Name Stmts Miss Cover Missing
169 # --------------------------------------------
170 # mymissing.py 14 3 79% 3-4, 10
171
172 self.assertEqual(self.line_count(report), 3)
173 self.assertIn("mymissing.py ", report)
174 self.assertEqual(self.last_line_squeezed(report),
175 "mymissing.py 14 3 79% 3-4, 10")
176
177 def test_report_show_missing_branches(self):
178 self.make_file("mybranch.py", """\
179 def branch(x, y):
180 if x:
181 print("x")
182 if y:
183 print("y")
184 return x
185 branch(1, 1)
186 """)
187 out = self.run_command("coverage run --branch mybranch.py")
188 self.assertEqual(out, 'x\ny\n')
189 report = self.report_from_command("coverage report --show-missing")
190
191 # Name Stmts Miss Branch BrPart Cover Missing
192 # ----------------------------------------------------------
193 # mybranch.py 7 0 4 2 82% 2->4, 4->6
194
195 self.assertEqual(self.line_count(report), 3)
196 self.assertIn("mybranch.py ", report)
197 self.assertEqual(self.last_line_squeezed(report),
198 "mybranch.py 7 0 4 2 82% 2->4, 4->6")
199
200 def test_report_show_missing_branches_and_lines(self):
201 self.make_file("main.py", """\
202 import mybranch
203 """)
204 self.make_file("mybranch.py", """\
205 def branch(x, y, z):
206 if x:
207 print("x")
208 if y:
209 print("y")
210 if z:
211 if x and y:
212 print("z")
213 return x
214 branch(1, 1, 0)
215 """)
216 out = self.run_command("coverage run --branch main.py")
217 self.assertEqual(out, 'x\ny\n')
218 report = self.report_from_command("coverage report --show-missing")
219
220 # Name Stmts Miss Branch BrPart Cover Missing
221 # -------------------------------------------------------
222 # main.py 1 0 0 0 100%
223 # mybranch.py 10 2 8 3 61% 7-8, 2->4, 4->6, 6->7
224 # -------------------------------------------------------
225 # TOTAL 11 2 8 3 63%
226
227 self.assertEqual(self.line_count(report), 6)
228 squeezed = self.squeezed_lines(report)
229 self.assertEqual(
230 squeezed[2],
231 "main.py 1 0 0 0 100%"
232 )
233 self.assertEqual(
234 squeezed[3],
235 "mybranch.py 10 2 8 3 61% 7-8, 2->4, 4->6, 6->7"
236 )
237 self.assertEqual(
238 squeezed[5],
239 "TOTAL 11 2 8 3 63%"
240 )
241
242 def test_report_skip_covered_no_branches(self):
243 self.make_file("main.py", """
244 import not_covered
245
246 def normal():
247 print("z")
248 normal()
249 """)
250 self.make_file("not_covered.py", """
251 def not_covered():
252 print("n")
253 """)
254 out = self.run_command("coverage run main.py")
255 self.assertEqual(out, "z\n")
256 report = self.report_from_command("coverage report --skip-covered")
257
258 # Name Stmts Miss Cover
259 # ------------------------------------
260 # not_covered.py 2 1 50%
261 #
262 # 1 file skipped due to complete coverage.
263
264 self.assertEqual(self.line_count(report), 5, report)
265 squeezed = self.squeezed_lines(report)
266 self.assertEqual(squeezed[2], "not_covered.py 2 1 50%")
267
268 def test_report_skip_covered_branches(self):
269 self.make_file("main.py", """
270 import not_covered, covered
271
272 def normal(z):
273 if z:
274 print("z")
275 normal(True)
276 normal(False)
277 """)
278 self.make_file("not_covered.py", """
279 def not_covered(n):
280 if n:
281 print("n")
282 not_covered(True)
283 """)
284 self.make_file("covered.py", """
285 def foo():
286 pass
287 foo()
288 """)
289 out = self.run_command("coverage run --branch main.py")
290 self.assertEqual(out, "n\nz\n")
291 report = self.report_from_command("coverage report --skip-covered")
292
293 # Name Stmts Miss Branch BrPart Cover
294 # --------------------------------------------------
295 # not_covered.py 4 0 2 1 83%
296 #
297 # 2 files skipped due to complete coverage.
298
299 self.assertEqual(self.line_count(report), 5, report)
300 squeezed = self.squeezed_lines(report)
301 self.assertEqual(squeezed[2], "not_covered.py 4 0 2 1 83%")
302
303 def test_report_skip_covered_branches_with_totals(self):
304 self.make_file("main.py", """
305 import not_covered
306 import also_not_run
307
308 def normal(z):
309 if z:
310 print("z")
311 normal(True)
312 normal(False)
313 """)
314 self.make_file("not_covered.py", """
315 def not_covered(n):
316 if n:
317 print("n")
318 not_covered(True)
319 """)
320 self.make_file("also_not_run.py", """
321 def does_not_appear_in_this_film(ni):
322 print("Ni!")
323 """)
324 out = self.run_command("coverage run --branch main.py")
325 self.assertEqual(out, "n\nz\n")
326 report = self.report_from_command("coverage report --skip-covered")
327
328 # Name Stmts Miss Branch BrPart Cover
329 # --------------------------------------------------
330 # also_not_run.py 2 1 0 0 50%
331 # not_covered.py 4 0 2 1 83%
332 # --------------------------------------------------
333 # TOTAL 6 1 2 1 75%
334 #
335 # 1 file skipped due to complete coverage.
336
337 self.assertEqual(self.line_count(report), 8, report)
338 squeezed = self.squeezed_lines(report)
339 self.assertEqual(squeezed[2], "also_not_run.py 2 1 0 0 50%")
340 self.assertEqual(squeezed[3], "not_covered.py 4 0 2 1 83%")
341 self.assertEqual(squeezed[5], "TOTAL 6 1 2 1 75%")
342 self.assertEqual(squeezed[7], "1 file skipped due to complete coverage." )
343
344 def test_report_skip_covered_all_files_covered(self):
345 self.make_file("main.py", """
346 def foo():
347 pass
348 foo()
349 """)
350 out = self.run_command("coverage run --branch main.py")
351 self.assertEqual(out, "")
352 report = self.report_from_command("coverage report --skip-covered")
353
354 # Name Stmts Miss Branch BrPart Cover
355 # -------------------------------------------
356 #
357 # 1 file skipped due to complete coverage.
358
359 self.assertEqual(self.line_count(report), 4, report)
360 squeezed = self.squeezed_lines(report)
361 self.assertEqual(squeezed[3], "1 file skipped due to complete coverage." )
362
363 def test_report_skip_covered_no_data(self):
364 report = self.report_from_command("coverage report --skip-covered")
365
366 # Name Stmts Miss Branch BrPart Cover
367 # -------------------------------------------
368 # No data to report.
369
370 self.assertEqual(self.line_count(report), 3, report)
371 squeezed = self.squeezed_lines(report)
372 self.assertEqual(squeezed[2], "No data to report.")
373
374 def test_dotpy_not_python(self):
375 # We run a .py file, and when reporting, we can't parse it as Python.
376 # We should get an error message in the report.
377
378 self.make_mycode()
379 self.run_command("coverage run mycode.py")
380 self.make_file("mycode.py", "This isn't python at all!")
381 report = self.report_from_command("coverage report mycode.py")
382
383 # Name Stmts Miss Cover
384 # ----------------------------
385 # mycode NotPython: Couldn't parse '...' as Python source: 'invalid sy ntax' at line 1
386 # No data to report.
387
388 last = self.squeezed_lines(report)[-2]
389 # The actual file name varies run to run.
390 last = re.sub(r"parse '.*mycode.py", "parse 'mycode.py", last)
391 # The actual error message varies version to version
392 last = re.sub(r": '.*' at", ": 'error' at", last)
393 self.assertEqual(
394 last,
395 "mycode.py NotPython: Couldn't parse 'mycode.py' as Python source: ' error' at line 1"
396 )
397
398 def test_dotpy_not_python_ignored(self):
399 # We run a .py file, and when reporting, we can't parse it as Python,
400 # but we've said to ignore errors, so there's no error reported.
401 self.make_mycode()
402 self.run_command("coverage run mycode.py")
403 self.make_file("mycode.py", "This isn't python at all!")
404 report = self.report_from_command("coverage report -i mycode.py")
405
406 # Name Stmts Miss Cover
407 # ----------------------------
408
409 self.assertEqual(self.line_count(report), 3)
410 self.assertIn('No data to report.', report)
411
412 def test_dothtml_not_python(self):
413 # We run a .html file, and when reporting, we can't parse it as
414 # Python. Since it wasn't .py, no error is reported.
415
416 # Run an "html" file
417 self.make_file("mycode.html", "a = 1")
418 self.run_command("coverage run mycode.html")
419 # Before reporting, change it to be an HTML file.
420 self.make_file("mycode.html", "<h1>This isn't python at all!</h1>")
421 report = self.report_from_command("coverage report mycode.html")
422
423 # Name Stmts Miss Cover
424 # ----------------------------
425 # No data to report.
426
427 self.assertEqual(self.line_count(report), 3)
428 self.assertIn('No data to report.', report)
429
430 def get_report(self, cov):
431 """Get the report from `cov`, and canonicalize it."""
432 repout = StringIO()
433 cov.report(file=repout, show_missing=False)
434 report = repout.getvalue().replace('\\', '/')
435 report = re.sub(r" +", " ", report)
436 return report
437
438 def test_bug_156_file_not_run_should_be_zero(self):
439 # https://bitbucket.org/ned/coveragepy/issue/156
440 self.make_file("mybranch.py", """\
441 def branch(x):
442 if x:
443 print("x")
444 return x
445 branch(1)
446 """)
447 self.make_file("main.py", """\
448 print("y")
449 """)
450 cov = coverage.Coverage(branch=True, source=["."])
451 cov.start()
452 import main # pragma: nested # pylint: disable=import-error,unused-v ariable
453 cov.stop() # pragma: nested
454 report = self.get_report(cov).splitlines()
455 self.assertIn("mybranch.py 5 5 2 0 0%", report)
456
457 def run_TheCode_and_report_it(self):
458 """A helper for the next few tests."""
459 cov = coverage.Coverage()
460 cov.start()
461 import TheCode # pragma: nested # pylint: disable=import-error,unused-v ariable
462 cov.stop() # pragma: nested
463 return self.get_report(cov)
464
465 def test_bug_203_mixed_case_listed_twice_with_rc(self):
466 self.make_file("TheCode.py", "a = 1\n")
467 self.make_file(".coveragerc", "[run]\nsource = .\n")
468
469 report = self.run_TheCode_and_report_it()
470
471 self.assertIn("TheCode", report)
472 self.assertNotIn("thecode", report)
473
474 def test_bug_203_mixed_case_listed_twice(self):
475 self.make_file("TheCode.py", "a = 1\n")
476
477 report = self.run_TheCode_and_report_it()
478
479 self.assertIn("TheCode", report)
480 self.assertNotIn("thecode", report)
481
482 def test_pyw_files(self):
483 if not env.WINDOWS:
484 self.skip(".pyw files are only on Windows.")
485
486 # https://bitbucket.org/ned/coveragepy/issue/261
487 self.make_file("start.pyw", """\
488 import mod
489 print("In start.pyw")
490 """)
491 self.make_file("mod.pyw", """\
492 print("In mod.pyw")
493 """)
494 cov = coverage.Coverage()
495 cov.start()
496 import start # pragma: nested # pylint: disable=import-error,unused-v ariable
497 cov.stop() # pragma: nested
498
499 report = self.get_report(cov)
500 self.assertNotIn("NoSource", report)
501 report = report.splitlines()
502 self.assertIn("start.pyw 2 0 100%", report)
503 self.assertIn("mod.pyw 1 0 100%", report)
504
505 def test_tracing_pyc_file(self):
506 # Create two Python files.
507 self.make_file("mod.py", "a = 1\n")
508 self.make_file("main.py", "import mod\n")
509
510 # Make one into a .pyc.
511 py_compile.compile("mod.py")
512
513 # Run the program.
514 cov = coverage.Coverage()
515 cov.start()
516 import main # pragma: nested # pylint: disable=import-error,unused-v ariable
517 cov.stop() # pragma: nested
518
519 report = self.get_report(cov).splitlines()
520 self.assertIn("mod.py 1 0 100%", report)
521
522 def test_missing_py_file_during_run(self):
523 # PyPy2 doesn't run bare .pyc files.
524 if env.PYPY and env.PY2:
525 self.skip("PyPy2 doesn't run bare .pyc files")
526
527 # Create two Python files.
528 self.make_file("mod.py", "a = 1\n")
529 self.make_file("main.py", "import mod\n")
530
531 # Make one into a .pyc, and remove the .py.
532 py_compile.compile("mod.py")
533 os.remove("mod.py")
534
535 # Python 3 puts the .pyc files in a __pycache__ directory, and will
536 # not import from there without source. It will import a .pyc from
537 # the source location though.
538 if not os.path.exists("mod.pyc"):
539 pycs = glob.glob("__pycache__/mod.*.pyc")
540 self.assertEqual(len(pycs), 1)
541 os.rename(pycs[0], "mod.pyc")
542
543 # Run the program.
544 cov = coverage.Coverage()
545 cov.start()
546 import main # pragma: nested # pylint: disable=import-error,unused-v ariable
547 cov.stop() # pragma: nested
548
549 # Put back the missing Python file.
550 self.make_file("mod.py", "a = 1\n")
551 report = self.get_report(cov).splitlines()
552 self.assertIn("mod.py 1 0 100%", report)
553
554
555 class SummaryTest2(CoverageTest):
556 """Another bunch of summary tests."""
557 # This class exists because tests naturally clump into classes based on the
558 # needs of their setUp, rather than the product features they are testing.
559 # There's probably a better way to organize these.
560
561 run_in_temp_dir = False
562
563 def setUp(self):
564 super(SummaryTest2, self).setUp()
565 # Parent class saves and restores sys.path, we can just modify it.
566 sys.path.append(self.nice_file(HERE, 'modules'))
567 sys.path.append(self.nice_file(HERE, 'moremodules'))
568
569 def test_empty_files(self):
570 # Shows that empty files like __init__.py are listed as having zero
571 # statements, not one statement.
572 cov = coverage.Coverage()
573 cov.start()
574 import usepkgs # pragma: nested # pylint: disable=import-error,unused-v ariable
575 cov.stop() # pragma: nested
576
577 repout = StringIO()
578 cov.report(file=repout, show_missing=False)
579
580 report = repout.getvalue().replace('\\', '/')
581 report = re.sub(r"\s+", " ", report)
582 self.assertIn("tests/modules/pkg1/__init__.py 1 0 100%", report)
583 self.assertIn("tests/modules/pkg2/__init__.py 0 0 100%", report)
584
585
586 class ReportingReturnValueTest(CoverageTest):
587 """Tests of reporting functions returning values."""
588
589 def run_coverage(self):
590 """Run coverage on doit.py and return the coverage object."""
591 self.make_file("doit.py", """\
592 a = 1
593 b = 2
594 c = 3
595 d = 4
596 if a > 10:
597 f = 6
598 g = 7
599 """)
600
601 cov = coverage.Coverage()
602 self.start_import_stop(cov, "doit")
603 return cov
604
605 def test_report(self):
606 cov = self.run_coverage()
607 val = cov.report(include="*/doit.py")
608 self.assertAlmostEqual(val, 85.7, 1)
609
610 def test_html(self):
611 cov = self.run_coverage()
612 val = cov.html_report(include="*/doit.py")
613 self.assertAlmostEqual(val, 85.7, 1)
614
615 def test_xml(self):
616 cov = self.run_coverage()
617 val = cov.xml_report(include="*/doit.py")
618 self.assertAlmostEqual(val, 85.7, 1)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698