# coding: utf-8 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt """Tests for coverage.py.""" import coverage from coverage import env from coverage.misc import CoverageException from tests.coveragetest import CoverageTest class TestCoverageTest(CoverageTest): """Make sure our complex self.check_coverage method works.""" def test_successful_coverage(self): # The simplest run possible. self.check_coverage("""\ a = 1 b = 2 """, [1,2] ) # You can provide a list of possible statement matches. self.check_coverage("""\ a = 1 b = 2 """, ([100], [1,2], [1723,47]), ) # You can specify missing lines. self.check_coverage("""\ a = 1 if a == 2: a = 3 """, [1,2,3], missing="3", ) # You can specify a list of possible missing lines. self.check_coverage("""\ a = 1 if a == 2: a = 3 """, [1,2,3], missing=("47-49", "3", "100,102") ) def test_failed_coverage(self): # If the lines are wrong, the message shows right and wrong. with self.assertRaisesRegex(AssertionError, r"\[1, 2] != \[1]"): self.check_coverage("""\ a = 1 b = 2 """, [1] ) # If the list of lines possibilities is wrong, the msg shows right. msg = r"None of the lines choices matched \[1, 2]" with self.assertRaisesRegex(AssertionError, msg): self.check_coverage("""\ a = 1 b = 2 """, ([1], [2]) ) # If the missing lines are wrong, the message shows right and wrong. with self.assertRaisesRegex(AssertionError, r"'3' != '37'"): self.check_coverage("""\ a = 1 if a == 2: a = 3 """, [1,2,3], missing="37", ) # If the missing lines possibilities are wrong, the msg shows right. msg = r"None of the missing choices matched '3'" with self.assertRaisesRegex(AssertionError, msg): self.check_coverage("""\ a = 1 if a == 2: a = 3 """, [1,2,3], missing=("37", "4-10"), ) class BasicCoverageTest(CoverageTest): """The simplest tests, for quick smoke testing of fundamental changes.""" def test_simple(self): self.check_coverage("""\ a = 1 b = 2 c = 4 # Nothing here d = 6 """, [1,2,4,6], report="4 0 0 0 100%") def test_indentation_wackiness(self): # Partial final lines are OK. self.check_coverage("""\ import sys if not sys.path: a = 1 """, # indented last line [1,2,3], "3") def test_multiline_initializer(self): self.check_coverage("""\ d = { 'foo': 1+2, 'bar': (lambda x: x+1)(1), 'baz': str(1), } e = { 'foo': 1, 'bar': 2 } """, [1,7], "") def test_list_comprehension(self): self.check_coverage("""\ l = [ 2*i for i in range(10) if i > 5 ] assert l == [12, 14, 16, 18] """, [1,5], "") class SimpleStatementTest(CoverageTest): """Testing simple single-line statements.""" def test_expression(self): # Bare expressions as statements are tricky: some implementations # optimize some of them away. All implementations seem to count # the implicit return at the end as executable. self.check_coverage("""\ 12 23 """, ([1,2],[2]), "") self.check_coverage("""\ 12 23 a = 3 """, ([1,2,3],[3]), "") self.check_coverage("""\ 1 + 2 1 + \\ 2 """, ([1,2], [2]), "") self.check_coverage("""\ 1 + 2 1 + \\ 2 a = 4 """, ([1,2,4], [4]), "") def test_assert(self): self.check_coverage("""\ assert (1 + 2) assert (1 + 2) assert (1 + 2), 'the universe is broken' assert (1 + 2), \\ 'something is amiss' """, [1,2,4,5], "") def test_assignment(self): # Simple variable assignment self.check_coverage("""\ a = (1 + 2) b = (1 + 2) c = \\ 1 """, [1,2,4], "") def test_assign_tuple(self): self.check_coverage("""\ a = 1 a,b,c = 7,8,9 assert a == 7 and b == 8 and c == 9 """, [1,2,3], "") def test_more_assignments(self): self.check_coverage("""\ x = [] d = {} d[ 4 + len(x) + 5 ] = \\ d[ 8 ** 2 ] = \\ 9 """, [1, 2, 3], "") def test_attribute_assignment(self): # Attribute assignment self.check_coverage("""\ class obj: pass o = obj() o.foo = (1 + 2) o.foo = (1 + 2) o.foo = \\ 1 """, [1,2,3,4,6], "") def test_list_of_attribute_assignment(self): self.check_coverage("""\ class obj: pass o = obj() o.a, o.b = (1 + 2), 3 o.a, o.b = (1 + 2), (3 + 4) o.a, o.b = \\ 1, \\ 2 """, [1,2,3,4,7], "") def test_augmented_assignment(self): self.check_coverage("""\ a = 1 a += 1 a += (1 + 2) a += \\ 1 """, [1,2,3,5], "") def test_triple_string_stuff(self): self.check_coverage("""\ a = ''' a multiline string. ''' b = ''' long expression ''' + ''' on many lines. ''' c = len(''' long expression ''' + ''' on many lines. ''') """, [1,5,11], "") def test_pass(self): # pass is tricky: if it's the only statement in a block, then it is # "executed". But if it is not the only statement, then it is not. self.check_coverage("""\ if 1==1: pass """, [1,2], "") self.check_coverage("""\ def foo(): pass foo() """, [1,2,3], "") self.check_coverage("""\ def foo(): "doc" pass foo() """, ([1,3,4], [1,4]), "") self.check_coverage("""\ class Foo: def foo(self): pass Foo().foo() """, [1,2,3,4], "") self.check_coverage("""\ class Foo: def foo(self): "Huh?" pass Foo().foo() """, ([1,2,4,5], [1,2,5]), "") def test_del(self): self.check_coverage("""\ d = { 'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1 } del d['a'] del d[ 'b' ] del d['c'], \\ d['d'], \\ d['e'] assert(len(d.keys()) == 0) """, [1,2,3,6,9], "") def test_print(self): if env.PY3: # Print statement is gone in Py3k. self.skipTest("No more print statement in Python 3.") self.check_coverage("""\ print "hello, world!" print ("hey: %d" % 17) print "goodbye" print "hello, world!", print ("hey: %d" % 17), print "goodbye", """, [1,2,4,5,6,8], "") def test_raise(self): self.check_coverage("""\ try: raise Exception( "hello %d" % 17) except: pass """, [1,2,5,6], "") def test_return(self): self.check_coverage("""\ def fn(): a = 1 return a x = fn() assert(x == 1) """, [1,2,3,5,6], "") self.check_coverage("""\ def fn(): a = 1 return ( a + 1) x = fn() assert(x == 2) """, [1,2,3,7,8], "") self.check_coverage("""\ def fn(): a = 1 return (a, a + 1, a + 2) x,y,z = fn() assert x == 1 and y == 2 and z == 3 """, [1,2,3,7,8], "") def test_yield(self): self.check_coverage("""\ def gen(): yield 1 yield (2+ 3+ 4) yield 1, \\ 2 a,b,c = gen() assert a == 1 and b == 9 and c == (1,2) """, [1,2,3,6,8,9], "") def test_break(self): self.check_coverage("""\ for x in range(10): a = 2 + x break a = 4 assert a == 2 """, [1,2,3,4,5], "4") def test_continue(self): self.check_coverage("""\ for x in range(10): a = 2 + x continue a = 4 assert a == 11 """, [1,2,3,4,5], "4") def test_strange_unexecuted_continue(self): # pragma: not covered # Peephole optimization of jumps to jumps can mean that some statements # never hit the line tracer. The behavior is different in different # versions of Python, so don't run this test: self.skipTest("Expected failure: peephole optimization of jumps to jumps") self.check_coverage("""\ a = b = c = 0 for n in range(100): if n % 2: if n % 4: a += 1 continue # <-- This line may not be hit. else: b += 1 c += 1 assert a == 50 and b == 50 and c == 50 a = b = c = 0 for n in range(100): if n % 2: if n % 3: a += 1 continue # <-- This line is always hit. else: b += 1 c += 1 assert a == 33 and b == 50 and c == 50 """, [1,2,3,4,5,6,8,9,10, 12,13,14,15,16,17,19,20,21], "") def test_import(self): self.check_coverage("""\ import string from sys import path a = 1 """, [1,2,3], "") self.check_coverage("""\ import string if 1 == 2: from sys import path a = 1 """, [1,2,3,4], "3") self.check_coverage("""\ import string, \\ os, \\ re from sys import path, \\ stdout a = 1 """, [1,4,6], "") self.check_coverage("""\ import sys, sys as s assert s.path == sys.path """, [1,2], "") self.check_coverage("""\ import sys, \\ sys as s assert s.path == sys.path """, [1,3], "") self.check_coverage("""\ from sys import path, \\ path as p assert p == path """, [1,3], "") self.check_coverage("""\ from sys import \\ * assert len(path) > 0 """, [1,3], "") def test_global(self): self.check_coverage("""\ g = h = i = 1 def fn(): global g global h, \\ i g = h = i = 2 fn() assert g == 2 and h == 2 and i == 2 """, [1,2,6,7,8], "") self.check_coverage("""\ g = h = i = 1 def fn(): global g; g = 2 fn() assert g == 2 and h == 1 and i == 1 """, [1,2,3,4,5], "") def test_exec(self): self.check_coverage("""\ a = b = c = 1 exec("a = 2") exec("b = " + "c = " + "2") assert a == 2 and b == 2 and c == 2 """, [1,2,3,6], "") self.check_coverage("""\ vars = {'a': 1, 'b': 1, 'c': 1} exec("a = 2", vars) exec("b = " + "c = " + "2", vars) assert vars['a'] == 2 and vars['b'] == 2 and vars['c'] == 2 """, [1,2,3,6], "") self.check_coverage("""\ globs = {} locs = {'a': 1, 'b': 1, 'c': 1} exec("a = 2", globs, locs) exec("b = " + "c = " + "2", globs, locs) assert locs['a'] == 2 and locs['b'] == 2 and locs['c'] == 2 """, [1,2,3,4,7], "") def test_extra_doc_string(self): self.check_coverage("""\ a = 1 "An extra docstring, should be a comment." b = 3 assert (a,b) == (1,3) """, [1,3,4], "") self.check_coverage("""\ a = 1 "An extra docstring, should be a comment." b = 3 123 # A number for some reason: ignored 1+1 # An expression: executed. c = 6 assert (a,b,c) == (1,3,6) """, ([1,3,6,7], [1,3,5,6,7], [1,3,4,5,6,7]), "") def test_nonascii(self): self.check_coverage("""\ # coding: utf-8 a = 2 b = 3 """, [2, 3] ) def test_module_docstring(self): self.check_coverage("""\ '''I am a module docstring.''' a = 2 b = 3 """, [2, 3] ) if env.PYVERSION < (3, 7): # Before 3.7, module docstrings were included in the lnotab table, # unless they were the first line in the file? lines = [2, 3, 4] else: lines = [3, 4] self.check_coverage("""\ # Start with a comment, because it changes the behavior(!?) '''I am a module docstring.''' a = 3 b = 4 """, lines ) class CompoundStatementTest(CoverageTest): """Testing coverage of multi-line compound statements.""" def test_statement_list(self): self.check_coverage("""\ a = 1; b = 2; c = 3 d = 4; e = 5; assert (a,b,c,d,e) == (1,2,3,4,5) """, [1,2,3,5], "") def test_if(self): self.check_coverage("""\ a = 1 if a == 1: x = 3 assert x == 3 if (a == 1): x = 7 assert x == 7 """, [1,2,3,4,5,7,8], "") self.check_coverage("""\ a = 1 if a == 1: x = 3 else: y = 5 assert x == 3 """, [1,2,3,5,6], "5") self.check_coverage("""\ a = 1 if a != 1: x = 3 else: y = 5 assert y == 5 """, [1,2,3,5,6], "3") self.check_coverage("""\ a = 1; b = 2 if a == 1: if b == 2: x = 4 else: y = 6 else: z = 8 assert x == 4 """, [1,2,3,4,6,8,9], "6-8") def test_elif(self): self.check_coverage("""\ a = 1; b = 2; c = 3; if a == 1: x = 3 elif b == 2: y = 5 else: z = 7 assert x == 3 """, [1,2,3,4,5,7,8], "4-7", report="7 3 4 1 45% 4-7, 2->4", ) self.check_coverage("""\ a = 1; b = 2; c = 3; if a != 1: x = 3 elif b == 2: y = 5 else: z = 7 assert y == 5 """, [1,2,3,4,5,7,8], "3, 7", report="7 2 4 2 64% 3, 7, 2->3, 4->7", ) self.check_coverage("""\ a = 1; b = 2; c = 3; if a != 1: x = 3 elif b != 2: y = 5 else: z = 7 assert z == 7 """, [1,2,3,4,5,7,8], "3, 5", report="7 2 4 2 64% 3, 5, 2->3, 4->5", ) def test_elif_no_else(self): self.check_coverage("""\ a = 1; b = 2; c = 3; if a == 1: x = 3 elif b == 2: y = 5 assert x == 3 """, [1,2,3,4,5,6], "4-5", report="6 2 4 1 50% 4-5, 2->4", ) self.check_coverage("""\ a = 1; b = 2; c = 3; if a != 1: x = 3 elif b == 2: y = 5 assert y == 5 """, [1,2,3,4,5,6], "3", report="6 1 4 2 70% 3, 2->3, 4->6", ) def test_elif_bizarre(self): self.check_coverage("""\ def f(self): if self==1: x = 3 elif self.m('fred'): x = 5 elif (g==1) and (b==2): x = 7 elif self.m('fred')==True: x = 9 elif ((g==1) and (b==2))==True: x = 11 else: x = 13 """, [1,2,3,4,5,6,7,8,9,10,11,13], "2-13") def test_split_if(self): self.check_coverage("""\ a = 1; b = 2; c = 3; if \\ a == 1: x = 3 elif \\ b == 2: y = 5 else: z = 7 assert x == 3 """, [1,2,4,5,7,9,10], "5-9") self.check_coverage("""\ a = 1; b = 2; c = 3; if \\ a != 1: x = 3 elif \\ b == 2: y = 5 else: z = 7 assert y == 5 """, [1,2,4,5,7,9,10], "4, 9") self.check_coverage("""\ a = 1; b = 2; c = 3; if \\ a != 1: x = 3 elif \\ b != 2: y = 5 else: z = 7 assert z == 7 """, [1,2,4,5,7,9,10], "4, 7") def test_pathological_split_if(self): self.check_coverage("""\ a = 1; b = 2; c = 3; if ( a == 1 ): x = 3 elif ( b == 2 ): y = 5 else: z = 7 assert x == 3 """, [1,2,5,6,9,11,12], "6-11") self.check_coverage("""\ a = 1; b = 2; c = 3; if ( a != 1 ): x = 3 elif ( b == 2 ): y = 5 else: z = 7 assert y == 5 """, [1,2,5,6,9,11,12], "5, 11") self.check_coverage("""\ a = 1; b = 2; c = 3; if ( a != 1 ): x = 3 elif ( b != 2 ): y = 5 else: z = 7 assert z == 7 """, [1,2,5,6,9,11,12], "5, 9") def test_absurd_split_if(self): self.check_coverage("""\ a = 1; b = 2; c = 3; if a == 1 \\ : x = 3 elif b == 2 \\ : y = 5 else: z = 7 assert x == 3 """, [1,2,4,5,7,9,10], "5-9") self.check_coverage("""\ a = 1; b = 2; c = 3; if a != 1 \\ : x = 3 elif b == 2 \\ : y = 5 else: z = 7 assert y == 5 """, [1,2,4,5,7,9,10], "4, 9") self.check_coverage("""\ a = 1; b = 2; c = 3; if a != 1 \\ : x = 3 elif b != 2 \\ : y = 5 else: z = 7 assert z == 7 """, [1,2,4,5,7,9,10], "4, 7") def test_constant_if(self): self.check_coverage("""\ if 1: a = 2 assert a == 2 """, [2,3], "") def test_while(self): self.check_coverage("""\ a = 3; b = 0 while a: b += 1 a -= 1 assert a == 0 and b == 3 """, [1,2,3,4,5], "") self.check_coverage("""\ a = 3; b = 0 while a: b += 1 break b = 99 assert a == 3 and b == 1 """, [1,2,3,4,5,6], "5") def test_while_else(self): # Take the else branch. self.check_coverage("""\ a = 3; b = 0 while a: b += 1 a -= 1 else: b = 99 assert a == 0 and b == 99 """, [1,2,3,4,6,7], "") # Don't take the else branch. self.check_coverage("""\ a = 3; b = 0 while a: b += 1 a -= 1 break b = 123 else: b = 99 assert a == 2 and b == 1 """, [1,2,3,4,5,6,8,9], "6-8") def test_split_while(self): self.check_coverage("""\ a = 3; b = 0 while \\ a: b += 1 a -= 1 assert a == 0 and b == 3 """, [1,2,4,5,6], "") self.check_coverage("""\ a = 3; b = 0 while ( a ): b += 1 a -= 1 assert a == 0 and b == 3 """, [1,2,5,6,7], "") def test_for(self): self.check_coverage("""\ a = 0 for i in [1,2,3,4,5]: a += i assert a == 15 """, [1,2,3,4], "") self.check_coverage("""\ a = 0 for i in [1, 2,3,4, 5]: a += i assert a == 15 """, [1,2,5,6], "") self.check_coverage("""\ a = 0 for i in [1,2,3,4,5]: a += i break a = 99 assert a == 1 """, [1,2,3,4,5,6], "5") def test_for_else(self): self.check_coverage("""\ a = 0 for i in range(5): a += i+1 else: a = 99 assert a == 99 """, [1,2,3,5,6], "") self.check_coverage("""\ a = 0 for i in range(5): a += i+1 break a = 99 else: a = 123 assert a == 1 """, [1,2,3,4,5,7,8], "5-7") def test_split_for(self): self.check_coverage("""\ a = 0 for \\ i in [1,2,3,4,5]: a += i assert a == 15 """, [1,2,4,5], "") self.check_coverage("""\ a = 0 for \\ i in [1, 2,3,4, 5]: a += i assert a == 15 """, [1,2,6,7], "") def test_try_except(self): self.check_coverage("""\ a = 0 try: a = 1 except: a = 99 assert a == 1 """, [1,2,3,4,5,6], "4-5") self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except: a = 99 assert a == 99 """, [1,2,3,4,5,6,7], "") self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except ImportError: a = 99 except: a = 123 assert a == 123 """, [1,2,3,4,5,6,7,8,9], "6") self.check_coverage("""\ a = 0 try: a = 1 raise IOError("foo") except ImportError: a = 99 except IOError: a = 17 except: a = 123 assert a == 17 """, [1,2,3,4,5,6,7,8,9,10,11], "6, 9-10") self.check_coverage("""\ a = 0 try: a = 1 except: a = 99 else: a = 123 assert a == 123 """, [1,2,3,4,5,7,8], "4-5", arcz=".1 12 23 45 58 37 78 8.", arcz_missing="45 58", ) self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except: a = 99 else: a = 123 assert a == 99 """, [1,2,3,4,5,6,8,9], "8", arcz=".1 12 23 34 45 56 69 89 9.", arcz_missing="89", ) def test_try_finally(self): self.check_coverage("""\ a = 0 try: a = 1 finally: a = 99 assert a == 99 """, [1,2,3,5,6], "") self.check_coverage("""\ a = 0; b = 0 try: a = 1 try: raise Exception("foo") finally: b = 123 except: a = 99 assert a == 99 and b == 123 """, [1,2,3,4,5,7,8,9,10], "") def test_function_def(self): self.check_coverage("""\ a = 99 def foo(): ''' docstring ''' return 1 a = foo() assert a == 1 """, [1,2,5,7,8], "") self.check_coverage("""\ def foo( a, b ): ''' docstring ''' return a+b x = foo(17, 23) assert x == 40 """, [1,7,9,10], "") self.check_coverage("""\ def foo( a = (lambda x: x*2)(10), b = ( lambda x: x+1 )(1) ): ''' docstring ''' return a+b x = foo() assert x == 22 """, [1,10,12,13], "") def test_class_def(self): if env.PYVERSION < (3, 7): arcz="-22 2D DE E-2 23 36 6A A-2 -68 8-6 -AB B-A" else: # Python 3.7 no longer includes class docstrings in the lnotab table. arcz="-22 2D DE E-2 26 6A A-2 -68 8-6 -AB B-A" self.check_coverage("""\ # A comment. class theClass: ''' the docstring. Don't be fooled. ''' def __init__(self): ''' Another docstring. ''' self.a = 1 def foo(self): return self.a x = theClass().foo() assert x == 1 """, [2, 6, 8, 10, 11, 13, 14], "", arcz=arcz, ) class ExcludeTest(CoverageTest): """Tests of the exclusion feature to mark lines as not covered.""" def test_default(self): # A number of forms of pragma comment are accepted. self.check_coverage("""\ a = 1 b = 2 # pragma: no cover c = 3 d = 4 #pragma NOCOVER e = 5 f = 6#\tpragma:\tno cover g = 7 """, [1,3,5,7] ) def test_simple(self): self.check_coverage("""\ a = 1; b = 2 if len([]): a = 4 # -cc """, [1,3], "", excludes=['-cc']) def test_two_excludes(self): self.check_coverage("""\ a = 1; b = 2 if a == 99: a = 4 # -cc b = 5 c = 6 # -xx assert a == 1 and b == 2 """, [1,3,5,7], "5", excludes=['-cc', '-xx']) def test_excluding_if_suite(self): self.check_coverage("""\ a = 1; b = 2 if len([]): # not-here a = 4 b = 5 c = 6 assert a == 1 and b == 2 """, [1,7], "", excludes=['not-here']) def test_excluding_if_but_not_else_suite(self): self.check_coverage("""\ a = 1; b = 2 if len([]): # not-here a = 4 b = 5 c = 6 else: a = 8 b = 9 assert a == 8 and b == 9 """, [1,8,9,10], "", excludes=['not-here']) def test_excluding_else_suite(self): self.check_coverage("""\ a = 1; b = 2 if 1==1: a = 4 b = 5 c = 6 else: #pragma: NO COVER a = 8 b = 9 assert a == 4 and b == 5 and c == 6 """, [1,3,4,5,6,10], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 1; b = 2 if 1==1: a = 4 b = 5 c = 6 # Lots of comments to confuse the else handler. # more. else: #pragma: NO COVER # Comments here too. a = 8 b = 9 assert a == 4 and b == 5 and c == 6 """, [1,3,4,5,6,17], "", excludes=['#pragma: NO COVER']) def test_excluding_elif_suites(self): self.check_coverage("""\ a = 1; b = 2 if 1==1: a = 4 b = 5 c = 6 elif 1==0: #pragma: NO COVER a = 8 b = 9 else: a = 11 b = 12 assert a == 4 and b == 5 and c == 6 """, [1,3,4,5,6,11,12,13], "11-12", excludes=['#pragma: NO COVER']) def test_excluding_oneline_if(self): self.check_coverage("""\ def foo(): a = 2 if len([]): x = 3 # no cover b = 4 foo() """, [1,2,4,6], "", excludes=["no cover"]) def test_excluding_a_colon_not_a_suite(self): self.check_coverage("""\ def foo(): l = list(range(10)) a = l[:3] # no cover b = 4 foo() """, [1,2,4,6], "", excludes=["no cover"]) def test_excluding_for_suite(self): self.check_coverage("""\ a = 0 for i in [1,2,3,4,5]: #pragma: NO COVER a += i assert a == 15 """, [1,4], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 for i in [1, 2,3,4, 5]: #pragma: NO COVER a += i assert a == 15 """, [1,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 for i in [1,2,3,4,5 ]: #pragma: NO COVER a += i break a = 99 assert a == 1 """, [1,7], "", excludes=['#pragma: NO COVER']) def test_excluding_for_else(self): self.check_coverage("""\ a = 0 for i in range(5): a += i+1 break a = 99 else: #pragma: NO COVER a = 123 assert a == 1 """, [1,2,3,4,5,8], "5", excludes=['#pragma: NO COVER']) def test_excluding_while(self): self.check_coverage("""\ a = 3; b = 0 while a*b: #pragma: NO COVER b += 1 break b = 99 assert a == 3 and b == 0 """, [1,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 3; b = 0 while ( a*b ): #pragma: NO COVER b += 1 break b = 99 assert a == 3 and b == 0 """, [1,8], "", excludes=['#pragma: NO COVER']) def test_excluding_while_else(self): self.check_coverage("""\ a = 3; b = 0 while a: b += 1 break b = 99 else: #pragma: NO COVER b = 123 assert a == 3 and b == 1 """, [1,2,3,4,5,8], "5", excludes=['#pragma: NO COVER']) def test_excluding_try_except(self): self.check_coverage("""\ a = 0 try: a = 1 except: #pragma: NO COVER a = 99 assert a == 1 """, [1,2,3,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except: a = 99 assert a == 99 """, [1,2,3,4,5,6,7], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except ImportError: #pragma: NO COVER a = 99 except: a = 123 assert a == 123 """, [1,2,3,4,7,8,9], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: a = 1 except: #pragma: NO COVER a = 99 else: a = 123 assert a == 123 """, [1,2,3,7,8], "", excludes=['#pragma: NO COVER'], arcz=".1 12 23 37 45 58 78 8.", arcz_missing="45 58", ) self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except: a = 99 else: #pragma: NO COVER a = 123 assert a == 99 """, [1,2,3,4,5,6,9], "", excludes=['#pragma: NO COVER'], arcz=".1 12 23 34 45 56 69 89 9.", arcz_missing="89", ) def test_excluding_try_except_pass(self): self.check_coverage("""\ a = 0 try: a = 1 except: #pragma: NO COVER x = 2 assert a == 1 """, [1,2,3,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except ImportError: #pragma: NO COVER x = 2 except: a = 123 assert a == 123 """, [1,2,3,4,7,8,9], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: a = 1 except: #pragma: NO COVER x = 2 else: a = 123 assert a == 123 """, [1,2,3,7,8], "", excludes=['#pragma: NO COVER'], arcz=".1 12 23 37 45 58 78 8.", arcz_missing="45 58", ) self.check_coverage("""\ a = 0 try: a = 1 raise Exception("foo") except: a = 99 else: #pragma: NO COVER x = 2 assert a == 99 """, [1,2,3,4,5,6,9], "", excludes=['#pragma: NO COVER'], arcz=".1 12 23 34 45 56 69 89 9.", arcz_missing="89", ) def test_excluding_if_pass(self): # From a comment on the coverage.py page by Michael McNeil Forbes: self.check_coverage("""\ def f(): if False: # pragma: no cover pass # This line still reported as missing if False: # pragma: no cover x = 1 # Now it is skipped. f() """, [1,7], "", excludes=["no cover"]) def test_excluding_function(self): self.check_coverage("""\ def fn(foo): #pragma: NO COVER a = 1 b = 2 c = 3 x = 1 assert x == 1 """, [6,7], "", excludes=['#pragma: NO COVER']) def test_excluding_method(self): self.check_coverage("""\ class Fooey: def __init__(self): self.a = 1 def foo(self): #pragma: NO COVER return self.a x = Fooey() assert x.a == 1 """, [1,2,3,8,9], "", excludes=['#pragma: NO COVER']) def test_excluding_class(self): self.check_coverage("""\ class Fooey: #pragma: NO COVER def __init__(self): self.a = 1 def foo(self): return self.a x = 1 assert x == 1 """, [8,9], "", excludes=['#pragma: NO COVER']) def test_excludes_non_ascii(self): self.check_coverage("""\ # coding: utf-8 a = 1; b = 2 if len([]): a = 5 # ✘cover """, [2, 4], "", excludes=['✘cover'] ) def test_formfeed(self): # https://bitbucket.org/ned/coveragepy/issues/461/multiline-asserts-need-too-many-pragma self.check_coverage("""\ x = 1 assert len([]) == 0, ( "This won't happen %s" % ("hello",) ) \f x = 6 assert len([]) == 0, ( "This won't happen %s" % ("hello",) ) """, [1, 6], "", excludes=['assert'], ) class Py24Test(CoverageTest): """Tests of new syntax in Python 2.4.""" def test_function_decorators(self): self.check_coverage("""\ def require_int(func): def wrapper(arg): assert isinstance(arg, int) return func(arg) return wrapper @require_int def p1(arg): return arg*2 assert p1(10) == 20 """, [1,2,3,4,6,8,10,12], "") def test_function_decorators_with_args(self): self.check_coverage("""\ def boost_by(extra): def decorator(func): def wrapper(arg): return extra*func(arg) return wrapper return decorator @boost_by(10) def boosted(arg): return arg*2 assert boosted(10) == 200 """, [1,2,3,4,5,6,8,10,12], "") def test_double_function_decorators(self): self.check_coverage("""\ def require_int(func): def wrapper(arg): assert isinstance(arg, int) return func(arg) return wrapper def boost_by(extra): def decorator(func): def wrapper(arg): return extra*func(arg) return wrapper return decorator @require_int @boost_by(10) def boosted1(arg): return arg*2 assert boosted1(10) == 200 @boost_by(10) @require_int def boosted2(arg): return arg*2 assert boosted2(10) == 200 """, ([1,2,3,4,5,7,8,9,10,11,12,14,15,17,19,21,22,24,26], [1,2,3,4,5,7,8,9,10,11,12,14, 17,19,21, 24,26]), "") class Py25Test(CoverageTest): """Tests of new syntax in Python 2.5.""" def test_with_statement(self): self.check_coverage("""\ class Managed: def __enter__(self): desc = "enter" def __exit__(self, type, value, tb): desc = "exit" m = Managed() with m: desc = "block1a" desc = "block1b" try: with m: desc = "block2" raise Exception("Boo!") except: desc = "caught" """, [1,2,3,5,6,8,9,10,11,13,14,15,16,17,18], "") def test_try_except_finally(self): self.check_coverage("""\ a = 0; b = 0 try: a = 1 except: a = 99 finally: b = 2 assert a == 1 and b == 2 """, [1,2,3,4,5,7,8], "4-5", arcz=".1 12 23 37 45 57 78 8.", arcz_missing="45 57", ) self.check_coverage("""\ a = 0; b = 0 try: a = 1 raise Exception("foo") except: a = 99 finally: b = 2 assert a == 99 and b == 2 """, [1,2,3,4,5,6,8,9], "", arcz=".1 12 23 34 45 56 68 89 9.", ) self.check_coverage("""\ a = 0; b = 0 try: a = 1 raise Exception("foo") except ImportError: a = 99 except: a = 123 finally: b = 2 assert a == 123 and b == 2 """, [1,2,3,4,5,6,7,8,10,11], "6", arcz=".1 12 23 34 45 56 57 78 6A 8A AB B.", arcz_missing="56 6A", ) self.check_coverage("""\ a = 0; b = 0 try: a = 1 raise IOError("foo") except ImportError: a = 99 except IOError: a = 17 except: a = 123 finally: b = 2 assert a == 17 and b == 2 """, [1,2,3,4,5,6,7,8,9,10,12,13], "6, 9-10", arcz=".1 12 23 34 45 56 6C 57 78 8C 79 9A AC CD D.", arcz_missing="56 6C 79 9A AC", ) self.check_coverage("""\ a = 0; b = 0 try: a = 1 except: a = 99 else: a = 123 finally: b = 2 assert a == 123 and b == 2 """, [1,2,3,4,5,7,9,10], "4-5", arcz=".1 12 23 37 45 59 79 9A A.", arcz_missing="45 59", ) self.check_coverage("""\ a = 0; b = 0 try: a = 1 raise Exception("foo") except: a = 99 else: a = 123 finally: b = 2 assert a == 99 and b == 2 """, [1,2,3,4,5,6,8,10,11], "8", arcz=".1 12 23 34 45 56 6A 8A AB B.", arcz_missing="8A", ) class ModuleTest(CoverageTest): """Tests for the module-level behavior of the `coverage` module.""" run_in_temp_dir = False def test_not_singleton(self): # You *can* create another coverage object. coverage.Coverage() coverage.Coverage() def test_old_name_and_new_name(self): self.assertIs(coverage.coverage, coverage.Coverage) class ReportingTest(CoverageTest): """Tests of some reporting behavior.""" # We don't make any temporary files, but we need an empty directory to run # the tests in. no_files_in_temp_dir = True def test_no_data_to_report_on_annotate(self): # Reporting with no data produces a nice message and no output # directory. with self.assertRaisesRegex(CoverageException, "No data to report."): self.command_line("annotate -d ann") self.assert_doesnt_exist("ann") def test_no_data_to_report_on_html(self): # Reporting with no data produces a nice message and no output # directory. with self.assertRaisesRegex(CoverageException, "No data to report."): self.command_line("html -d htmlcov") self.assert_doesnt_exist("htmlcov") def test_no_data_to_report_on_xml(self): # Reporting with no data produces a nice message. with self.assertRaisesRegex(CoverageException, "No data to report."): self.command_line("xml") self.assert_doesnt_exist("coverage.xml")