blob: 947c5f1e9963cf5c60857409979c120beceb8e50 [file] [log] [blame]
# coding: utf-8
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/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"),
)
def test_exceptions_really_fail(self):
# An assert in the checked code will really raise up to us.
with self.assertRaisesRegex(AssertionError, "This is bad"):
self.check_coverage("""\
a = 1
assert a == 99, "This is bad"
"""
)
# Other exceptions too.
with self.assertRaisesRegex(ZeroDivisionError, "division"):
self.check_coverage("""\
a = 1
assert a == 1, "This is good"
a/0
"""
)
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]
)
lines = [2, 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):
arcz="-22 2D DE E-2 23 36 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):
lines = [1, 2, 3, 4, 6, 8, 10, 12]
if env.PYBEHAVIOR.trace_decorated_def:
lines = sorted(lines + [9])
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
""",
lines, "")
def test_function_decorators_with_args(self):
lines = [1, 2, 3, 4, 5, 6, 8, 10, 12]
if env.PYBEHAVIOR.trace_decorated_def:
lines = sorted(lines + [9])
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
""",
lines, "")
def test_double_function_decorators(self):
lines = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 14, 15, 17, 19, 21, 22, 24, 26]
if env.PYBEHAVIOR.trace_decorated_def:
lines = sorted(lines + [16, 23])
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
""",
lines, "")
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")