summaryrefslogtreecommitdiff
path: root/test_coverage.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-03-13 21:23:00 -0400
committerNed Batchelder <ned@nedbatchelder.com>2009-03-13 21:23:00 -0400
commit8e9454c81ae484f6fdc9af33403a71c35dda193e (patch)
tree0af3938008ab21221d912284be82d7a3df3ebf55 /test_coverage.py
parenteb8bd102097e9d177ec7c56e3948bcf265004119 (diff)
downloadpython-coveragepy-git-8e9454c81ae484f6fdc9af33403a71c35dda193e.tar.gz
Move the tests into the test directory.
--HG-- rename : coverage_coverage.py => test/coverage_coverage.py rename : test_coverage.py => test/test_coverage.py
Diffstat (limited to 'test_coverage.py')
-rw-r--r--test_coverage.py1979
1 files changed, 0 insertions, 1979 deletions
diff --git a/test_coverage.py b/test_coverage.py
deleted file mode 100644
index 4c2f8b6e..00000000
--- a/test_coverage.py
+++ /dev/null
@@ -1,1979 +0,0 @@
-# test coverage.py
-# Copyright 2004-2009, Ned Batchelder
-# http://nedbatchelder.com/code/modules/coverage.html
-
-# Change this 0 to 1 to get diagnostic output during testing.
-showstdout = 0
-
-import unittest
-import imp, os, pprint, random, sys, tempfile
-from cStringIO import StringIO
-
-import path # from http://www.jorendorff.com/articles/python/path/
-
-import coverage
-
-CovExc = coverage.CoverageException
-
-from textwrap import dedent
-
-
-coverage.use_cache(0)
-
-
-class CoverageTest(unittest.TestCase):
- def setUp(self):
- # Create a temporary directory.
- self.noise = str(random.random())[2:]
- self.temproot = path.path(tempfile.gettempdir()) / 'test_coverage'
- self.tempdir = self.temproot / self.noise
- self.tempdir.makedirs()
- self.olddir = os.getcwd()
- os.chdir(self.tempdir)
- # Keep a counter to make every call to checkCoverage unique.
- self.n = 0
-
- # Capture stdout, so we can use print statements in the tests and not
- # pollute the test output.
- self.oldstdout = sys.stdout
- self.capturedstdout = StringIO()
- if not showstdout:
- sys.stdout = self.capturedstdout
- coverage.begin_recursive()
-
- def tearDown(self):
- coverage.end_recursive()
- sys.stdout = self.oldstdout
- # Get rid of the temporary directory.
- os.chdir(self.olddir)
- self.temproot.rmtree()
-
- def getStdout(self):
- return self.capturedstdout.getvalue()
-
- def makeFile(self, modname, text):
- """ Create a temp file with modname as the module name, and text as the
- contents.
- """
- text = dedent(text)
-
- # Create the python file.
- f = open(modname + '.py', 'w')
- f.write(text)
- f.close()
-
- def importModule(self, modname):
- """ Import the module named modname, and return the module object.
- """
- modfile = modname + '.py'
- f = open(modfile, 'r')
-
- for suff in imp.get_suffixes():
- if suff[0] == '.py':
- break
- try:
- mod = imp.load_module(modname, f, modfile, suff)
- finally:
- f.close()
- return mod
-
- def getModuleName(self):
- # We append self.n because otherwise two calls in one test will use the
- # same filename and whether the test works or not depends on the
- # timestamps in the .pyc file, so it becomes random whether the second
- # call will use the compiled version of the first call's code or not!
- modname = 'coverage_test_' + self.noise + str(self.n)
- self.n += 1
- return modname
-
- def checkCoverage(self, text, lines, missing="", excludes=[], report=""):
- self.checkEverything(text=text, lines=lines, missing=missing, excludes=excludes, report=report)
-
- def checkEverything(self, text=None, file=None, lines=None, missing=None,
- excludes=[], report="", annfile=None):
- assert text or file
- assert not (text and file)
-
- # We write the code into a file so that we can import it.
- # coverage.py wants to deal with things as modules with file names.
- modname = self.getModuleName()
-
- if text:
- self.makeFile(modname, text)
- elif file:
- p = path.path(self.olddir) / file
- p.copyfile(modname + '.py')
-
- # Start up coverage.py
- coverage.erase()
- for exc in excludes:
- coverage.exclude(exc)
- coverage.start()
-
- # Import the python file, executing it.
- mod = self.importModule(modname)
-
- # Stop coverage.py
- coverage.stop()
-
- # Clean up our side effects
- del sys.modules[modname]
-
- # Get the analysis results, and check that they are right.
- _, clines, _, cmissing = coverage.analysis(mod)
- if lines is not None:
- if type(lines[0]) == type(1):
- self.assertEqual(clines, lines)
- else:
- for line_list in lines:
- if clines == line_list:
- break
- else:
- self.fail("None of the lines choices matched %r" % clines)
- if missing is not None:
- if type(missing) == type(""):
- self.assertEqual(cmissing, missing)
- else:
- for missing_list in missing:
- if cmissing == missing_list:
- break
- else:
- self.fail("None of the missing choices matched %r" % cmissing)
-
- if report:
- frep = StringIO()
- coverage.report(mod, file=frep)
- rep = " ".join(frep.getvalue().split("\n")[2].split()[1:])
- self.assertEqual(report, rep)
-
- if annfile:
- # Run annotate.
- coverage.annotate([modname+'.py'])
- expect = (path.path(self.olddir) / annfile).text()
- actual = path.path(modname + '.py,cover').text()
- # Write the actual results into a file for comparison.
- out = path.path(self.olddir) / (annfile + "_actual_%s%s" % (sys.version_info[:2]))
- # Check if the results are right
- if expect == actual:
- # They are right: delete the old test results if they are still
- # around.
- if out.exists():
- out.remove()
- else:
- # The results are wrong: write them out so we can diff them to
- # see what happened.
- out.write_text(actual)
- self.fail("Annotation is incorrect: %s" % out)
-
- def assertRaisesMsg(self, excClass, msg, callableObj, *args, **kwargs):
- """ Just like unittest.TestCase.assertRaises,
- but checks that the message is right too.
- """
- try:
- callableObj(*args, **kwargs)
- except excClass, exc:
- excMsg = str(exc)
- if not msg:
- # No message provided: it passes.
- return #pragma: no cover
- elif excMsg == msg:
- # Message provided, and we got the right message: it passes.
- return
- else: #pragma: no cover
- # Message provided, and it didn't match: fail!
- raise self.failureException("Right exception, wrong message: got '%s' expected '%s'" % (excMsg, msg))
- # No need to catch other exceptions: They'll fail the test all by themselves!
- else: #pragma: no cover
- if hasattr(excClass,'__name__'):
- excName = excClass.__name__
- else:
- excName = str(excClass)
- raise self.failureException("Expected to raise %s, didn't get an exception at all" % excName)
-
- def nice_file(self, *fparts):
- return os.path.normcase(os.path.abspath(os.path.realpath(os.path.join(*fparts))))
-
- def run_command(self, cmd):
- """ Run the command-line `cmd`, print its output.
- """
- # Add our test modules directory to PYTHONPATH. I'm sure there's too
- # much path munging here, but...
- here = os.path.dirname(self.nice_file(coverage.__file__, ".."))
- testmods = self.nice_file(here, 'test/modules')
- zipfile = self.nice_file(here, 'test/zipmods.zip')
- pypath = os.environ['PYTHONPATH']
- if pypath:
- pypath += os.pathsep
- pypath += testmods + os.pathsep + zipfile
- os.environ['PYTHONPATH'] = pypath
-
- stdin, stdouterr = os.popen4(cmd)
- output = stdouterr.read()
- if showstdout:
- print output
- return output
-
-
-class BasicCoverageTests(CoverageTest):
- def testSimple(self):
- self.checkCoverage("""\
- a = 1
- b = 2
-
- c = 4
- # Nothing here
- d = 6
- """,
- [1,2,4,6], report="4 4 100%")
-
- def testIndentationWackiness(self):
- # Partial final lines are OK.
- self.checkCoverage("""\
- import sys
- if not sys.path:
- a = 1
- """,
- [1,2,3], "3")
-
- def testMultilineInitializer(self):
- self.checkCoverage("""\
- d = {
- 'foo': 1+2,
- 'bar': (lambda x: x+1)(1),
- 'baz': str(1),
- }
-
- e = { 'foo': 1, 'bar': 2 }
- """,
- [1,7], "")
-
- def testListComprehension(self):
- self.checkCoverage("""\
- l = [
- 2*i for i in range(10)
- if i > 5
- ]
- assert l == [12, 14, 16, 18]
- """,
- [1,5], "")
-
-
-class SimpleStatementTests(CoverageTest):
- def testExpression(self):
- self.checkCoverage("""\
- 1 + 2
- 1 + \\
- 2
- """,
- [1,2], "")
-
- def testAssert(self):
- self.checkCoverage("""\
- assert (1 + 2)
- assert (1 +
- 2)
- assert (1 + 2), 'the universe is broken'
- assert (1 +
- 2), \\
- 'something is amiss'
- """,
- [1,2,4,5], "")
-
- def testAssignment(self):
- # Simple variable assignment
- self.checkCoverage("""\
- a = (1 + 2)
- b = (1 +
- 2)
- c = \\
- 1
- """,
- [1,2,4], "")
-
- def testAssignTuple(self):
- self.checkCoverage("""\
- a = 1
- a,b,c = 7,8,9
- assert a == 7 and b == 8 and c == 9
- """,
- [1,2,3], "")
-
- def testAttributeAssignment(self):
- # Attribute assignment
- self.checkCoverage("""\
- class obj: pass
- o = obj()
- o.foo = (1 + 2)
- o.foo = (1 +
- 2)
- o.foo = \\
- 1
- """,
- [1,2,3,4,6], "")
-
- def testListofAttributeAssignment(self):
- self.checkCoverage("""\
- 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 testAugmentedAssignment(self):
- self.checkCoverage("""\
- a = 1
- a += 1
- a += (1 +
- 2)
- a += \\
- 1
- """,
- [1,2,3,5], "")
-
- def testTripleStringStuff(self):
- self.checkCoverage("""\
- a = '''
- a multiline
- string.
- '''
- b = '''
- long expression
- ''' + '''
- on many
- lines.
- '''
- c = len('''
- long expression
- ''' +
- '''
- on many
- lines.
- ''')
- """,
- [1,5,11], "")
-
- def testPass(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.checkCoverage("""\
- if 1==1:
- pass
- """,
- [1,2], "")
- self.checkCoverage("""\
- def foo():
- pass
- foo()
- """,
- [1,2,3], "")
- self.checkCoverage("""\
- def foo():
- "doc"
- pass
- foo()
- """,
- ([1,3,4], [1,4]), "")
- self.checkCoverage("""\
- class Foo:
- def foo(self):
- pass
- Foo().foo()
- """,
- [1,2,3,4], "")
- self.checkCoverage("""\
- class Foo:
- def foo(self):
- "Huh?"
- pass
- Foo().foo()
- """,
- ([1,2,4,5], [1,2,5]), "")
-
- def testDel(self):
- self.checkCoverage("""\
- 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 testPrint(self):
- self.checkCoverage("""\
- 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 testRaise(self):
- self.checkCoverage("""\
- try:
- raise Exception(
- "hello %d" %
- 17)
- except:
- pass
- """,
- [1,2,5,6], "")
-
- def testReturn(self):
- self.checkCoverage("""\
- def fn():
- a = 1
- return a
-
- x = fn()
- assert(x == 1)
- """,
- [1,2,3,5,6], "")
- self.checkCoverage("""\
- def fn():
- a = 1
- return (
- a +
- 1)
-
- x = fn()
- assert(x == 2)
- """,
- [1,2,3,7,8], "")
- self.checkCoverage("""\
- 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 testYield(self):
- self.checkCoverage("""\
- from __future__ import generators
- 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,4,7,9,10], "")
-
- def testBreak(self):
- self.checkCoverage("""\
- for x in range(10):
- print "Hello"
- break
- print "Not here"
- """,
- [1,2,3,4], "4")
-
- def testContinue(self):
- self.checkCoverage("""\
- for x in range(10):
- print "Hello"
- continue
- print "Not here"
- """,
- [1,2,3,4], "4")
-
- if 0:
- # 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:
- def testStrangeUnexecutedContinue(self):
- self.checkCoverage("""\
- 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 testImport(self):
- self.checkCoverage("""\
- import string
- from sys import path
- a = 1
- """,
- [1,2,3], "")
- self.checkCoverage("""\
- import string
- if 1 == 2:
- from sys import path
- a = 1
- """,
- [1,2,3,4], "3")
- self.checkCoverage("""\
- import string, \\
- os, \\
- re
- from sys import path, \\
- stdout
- a = 1
- """,
- [1,4,6], "")
- self.checkCoverage("""\
- import sys, sys as s
- assert s.path == sys.path
- """,
- [1,2], "")
- self.checkCoverage("""\
- import sys, \\
- sys as s
- assert s.path == sys.path
- """,
- [1,3], "")
- self.checkCoverage("""\
- from sys import path, \\
- path as p
- assert p == path
- """,
- [1,3], "")
- self.checkCoverage("""\
- from sys import \\
- *
- assert len(path) > 0
- """,
- [1,3], "")
-
- def testGlobal(self):
- self.checkCoverage("""\
- 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.checkCoverage("""\
- 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 testExec(self):
- self.checkCoverage("""\
- 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.checkCoverage("""\
- vars = {'a': 1, 'b': 1, 'c': 1}
- exec "a = 2" in vars
- exec ("b = " +
- "c = " +
- "2") in vars
- assert vars['a'] == 2 and vars['b'] == 2 and vars['c'] == 2
- """,
- [1,2,3,6], "")
- self.checkCoverage("""\
- globs = {}
- locs = {'a': 1, 'b': 1, 'c': 1}
- exec "a = 2" in globs, locs
- exec ("b = " +
- "c = " +
- "2") in globs, locs
- assert locs['a'] == 2 and locs['b'] == 2 and locs['c'] == 2
- """,
- [1,2,3,4,7], "")
-
- def testExtraDocString(self):
- self.checkCoverage("""\
- a = 1
- "An extra docstring, should be a comment."
- b = 3
- assert (a,b) == (1,3)
- """,
- [1,3,4], "")
- self.checkCoverage("""\
- 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,5,6,7], [1,3,4,5,6,7]), "")
-
-
-class CompoundStatementTests(CoverageTest):
- def testStatementList(self):
- self.checkCoverage("""\
- 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 testIf(self):
- self.checkCoverage("""\
- 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.checkCoverage("""\
- a = 1
- if a == 1:
- x = 3
- else:
- y = 5
- assert x == 3
- """,
- [1,2,3,5,6], "5")
- self.checkCoverage("""\
- a = 1
- if a != 1:
- x = 3
- else:
- y = 5
- assert y == 5
- """,
- [1,2,3,5,6], "3")
- self.checkCoverage("""\
- 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 testElif(self):
- self.checkCoverage("""\
- 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 4 57% 4-7")
- self.checkCoverage("""\
- 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 5 71% 3, 7")
- self.checkCoverage("""\
- 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 5 71% 3, 5")
-
- def testElifNoElse(self):
- self.checkCoverage("""\
- 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 4 66% 4-5")
- self.checkCoverage("""\
- 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 5 83% 3")
-
- def testElifBizarre(self):
- self.checkCoverage("""\
- 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 testSplitIf(self):
- self.checkCoverage("""\
- 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.checkCoverage("""\
- 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.checkCoverage("""\
- 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 testPathologicalSplitIf(self):
- self.checkCoverage("""\
- 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.checkCoverage("""\
- 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.checkCoverage("""\
- 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 testAbsurdSplitIf(self):
- self.checkCoverage("""\
- 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.checkCoverage("""\
- 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.checkCoverage("""\
- 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 testWhile(self):
- self.checkCoverage("""\
- a = 3; b = 0
- while a:
- b += 1
- a -= 1
- assert a == 0 and b == 3
- """,
- [1,2,3,4,5], "")
- self.checkCoverage("""\
- 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 testWhileElse(self):
- # Take the else branch.
- self.checkCoverage("""\
- 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.checkCoverage("""\
- 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 testSplitWhile(self):
- self.checkCoverage("""\
- a = 3; b = 0
- while \\
- a:
- b += 1
- a -= 1
- assert a == 0 and b == 3
- """,
- [1,2,4,5,6], "")
- self.checkCoverage("""\
- a = 3; b = 0
- while (
- a
- ):
- b += 1
- a -= 1
- assert a == 0 and b == 3
- """,
- [1,2,5,6,7], "")
-
- def testFor(self):
- self.checkCoverage("""\
- a = 0
- for i in [1,2,3,4,5]:
- a += i
- assert a == 15
- """,
- [1,2,3,4], "")
- self.checkCoverage("""\
- a = 0
- for i in [1,
- 2,3,4,
- 5]:
- a += i
- assert a == 15
- """,
- [1,2,5,6], "")
- self.checkCoverage("""\
- 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 testForElse(self):
- self.checkCoverage("""\
- a = 0
- for i in range(5):
- a += i+1
- else:
- a = 99
- assert a == 99
- """,
- [1,2,3,5,6], "")
- self.checkCoverage("""\
- 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 testSplitFor(self):
- self.checkCoverage("""\
- a = 0
- for \\
- i in [1,2,3,4,5]:
- a += i
- assert a == 15
- """,
- [1,2,4,5], "")
- self.checkCoverage("""\
- a = 0
- for \\
- i in [1,
- 2,3,4,
- 5]:
- a += i
- assert a == 15
- """,
- [1,2,6,7], "")
-
- def testTryExcept(self):
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- except:
- a = 99
- assert a == 1
- """,
- [1,2,3,4,5,6], "4-5")
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- raise Exception("foo")
- except:
- a = 99
- assert a == 99
- """,
- [1,2,3,4,5,6,7], "")
- self.checkCoverage("""\
- 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.checkCoverage("""\
- 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.checkCoverage("""\
- a = 0
- try:
- a = 1
- except:
- a = 99
- else:
- a = 123
- assert a == 123
- """,
- [1,2,3,4,5,7,8], "4-5")
- self.checkCoverage("""\
- 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")
-
- def testTryFinally(self):
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- finally:
- a = 99
- assert a == 99
- """,
- [1,2,3,5,6], "")
- self.checkCoverage("""\
- 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 testFunctionDef(self):
- self.checkCoverage("""\
- a = 99
- def foo():
- ''' docstring
- '''
- return 1
-
- a = foo()
- assert a == 1
- """,
- [1,2,5,7,8], "")
- self.checkCoverage("""\
- def foo(
- a,
- b
- ):
- ''' docstring
- '''
- return a+b
-
- x = foo(17, 23)
- assert x == 40
- """,
- [1,7,9,10], "")
- self.checkCoverage("""\
- 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 testClassDef(self):
- self.checkCoverage("""\
- # 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], "")
-
-
-class ExcludeTests(CoverageTest):
- def testSimple(self):
- self.checkCoverage("""\
- a = 1; b = 2
-
- if 0:
- a = 4 # -cc
- """,
- [1,3], "", ['-cc'])
-
- def testTwoExcludes(self):
- self.checkCoverage("""\
- 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", ['-cc', '-xx'])
-
- def testExcludingIfSuite(self):
- self.checkCoverage("""\
- a = 1; b = 2
-
- if 0:
- a = 4
- b = 5
- c = 6
- assert a == 1 and b == 2
- """,
- [1,7], "", ['if 0:'])
-
- def testExcludingIfButNotElseSuite(self):
- self.checkCoverage("""\
- a = 1; b = 2
-
- if 0:
- a = 4
- b = 5
- c = 6
- else:
- a = 8
- b = 9
- assert a == 8 and b == 9
- """,
- [1,8,9,10], "", ['if 0:'])
-
- def testExcludingElseSuite(self):
- self.checkCoverage("""\
- 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], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- 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], "", ['#pragma: NO COVER'])
-
- def testExcludingElifSuites(self):
- self.checkCoverage("""\
- 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", ['#pragma: NO COVER'])
-
- def testExcludingOnelineIf(self):
- self.checkCoverage("""\
- def foo():
- a = 2
- if 0: x = 3 # no cover
- b = 4
-
- foo()
- """,
- [1,2,4,6], "", ["no cover"])
-
- def testExcludingAColonNotASuite(self):
- self.checkCoverage("""\
- def foo():
- l = range(10)
- print l[:3] # no cover
- b = 4
-
- foo()
- """,
- [1,2,4,6], "", ["no cover"])
-
- def testExcludingForSuite(self):
- self.checkCoverage("""\
- a = 0
- for i in [1,2,3,4,5]: #pragma: NO COVER
- a += i
- assert a == 15
- """,
- [1,4], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- a = 0
- for i in [1,
- 2,3,4,
- 5]: #pragma: NO COVER
- a += i
- assert a == 15
- """,
- [1,6], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- a = 0
- for i in [1,2,3,4,5
- ]: #pragma: NO COVER
- a += i
- break
- a = 99
- assert a == 1
- """,
- [1,7], "", ['#pragma: NO COVER'])
-
- def testExcludingForElse(self):
- self.checkCoverage("""\
- 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", ['#pragma: NO COVER'])
-
- def testExcludingWhile(self):
- self.checkCoverage("""\
- a = 3; b = 0
- while a*b: #pragma: NO COVER
- b += 1
- break
- b = 99
- assert a == 3 and b == 0
- """,
- [1,6], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- a = 3; b = 0
- while (
- a*b
- ): #pragma: NO COVER
- b += 1
- break
- b = 99
- assert a == 3 and b == 0
- """,
- [1,8], "", ['#pragma: NO COVER'])
-
- def testExcludingWhileElse(self):
- self.checkCoverage("""\
- 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", ['#pragma: NO COVER'])
-
- def testExcludingTryExcept(self):
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- except: #pragma: NO COVER
- a = 99
- assert a == 1
- """,
- [1,2,3,6], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- raise Exception("foo")
- except:
- a = 99
- assert a == 99
- """,
- [1,2,3,4,5,6,7], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- 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], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- except: #pragma: NO COVER
- a = 99
- else:
- a = 123
- assert a == 123
- """,
- [1,2,3,7,8], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- 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], "", ['#pragma: NO COVER'])
-
- def testExcludingTryExceptPass(self):
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- except: #pragma: NO COVER
- x = 2
- assert a == 1
- """,
- [1,2,3,6], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- 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], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- a = 0
- try:
- a = 1
- except: #pragma: NO COVER
- x = 2
- else:
- a = 123
- assert a == 123
- """,
- [1,2,3,7,8], "", ['#pragma: NO COVER'])
- self.checkCoverage("""\
- 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], "", ['#pragma: NO COVER'])
-
- def testExcludingIfPass(self):
- # From a comment on the coverage page by Michael McNeil Forbes:
- self.checkCoverage("""\
- 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], "", ["no cover"])
-
- def testExcludingFunction(self):
- self.checkCoverage("""\
- def fn(foo): #pragma: NO COVER
- a = 1
- b = 2
- c = 3
-
- x = 1
- assert x == 1
- """,
- [6,7], "", ['#pragma: NO COVER'])
-
- def testExcludingMethod(self):
- self.checkCoverage("""\
- 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], "", ['#pragma: NO COVER'])
-
- def testExcludingClass(self):
- self.checkCoverage("""\
- class Fooey: #pragma: NO COVER
- def __init__(self):
- self.a = 1
-
- def foo(self):
- return self.a
-
- x = 1
- assert x == 1
- """,
- [8,9], "", ['#pragma: NO COVER'])
-
-
-if sys.hexversion >= 0x020300f0:
- # threading support was new in 2.3, only test there.
- class ThreadingTests(CoverageTest):
- def testThreading(self):
- self.checkCoverage("""\
- import time, threading
-
- def fromMainThread():
- return "called from main thread"
-
- def fromOtherThread():
- return "called from other thread"
-
- def neverCalled():
- return "no one calls me"
-
- threading.Thread(target=fromOtherThread).start()
- fromMainThread()
- time.sleep(1)
- """,
- [1,3,4,6,7,9,10,12,13,14], "10")
-
-
-if sys.hexversion >= 0x020400f0:
- class Py24Tests(CoverageTest):
- def testFunctionDecorators(self):
- self.checkCoverage("""\
- 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 testFunctionDecoratorsWithArgs(self):
- self.checkCoverage("""\
- 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 testDoubleFunctionDecorators(self):
- self.checkCoverage("""\
- 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]), "")
-
-
-if sys.hexversion >= 0x020500f0:
- class Py25Tests(CoverageTest):
- def testWithStatement(self):
- self.checkCoverage("""\
- from __future__ import with_statement
-
- class Managed:
- def __enter__(self):
- print "enter"
-
- def __exit__(self, type, value, tb):
- print "exit", type
-
- m = Managed()
- with m:
- print "block1a"
- print "block1b"
-
- try:
- with m:
- print "block2"
- raise Exception("Boo!")
- except:
- print "caught"
- """,
- [1,3,4,5,7,8,10,11,12,13,15,16,17,18,19,20], "")
-
- def testTryExceptFinally(self):
- self.checkCoverage("""\
- 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")
- self.checkCoverage("""\
- 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], "")
- self.checkCoverage("""\
- 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")
- self.checkCoverage("""\
- 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")
- self.checkCoverage("""\
- 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")
- self.checkCoverage("""\
- 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")
-
-
-class ModuleTests(CoverageTest):
- def testNotSingleton(self):
- """ You *can* create another coverage object.
- """
- coverage.coverage()
- coverage.coverage()
-
-
-class ApiTests(CoverageTest):
- def testSimple(self):
- coverage.erase()
-
- self.makeFile("mycode", """\
- a = 1
- b = 2
- if b == 3:
- c = 4
- d = 5
- """)
-
- # Import the python file, executing it.
- coverage.start()
- self.importModule("mycode")
- coverage.stop()
-
- filename, statements, missing, readablemissing = coverage.analysis("mycode.py")
- self.assertEqual(statements, [1,2,3,4,5])
- self.assertEqual(missing, [4])
- self.assertEqual(readablemissing, "4")
-
- def doReportWork(self, modname):
- coverage.erase()
-
- self.makeFile(modname, """\
- a = 1
- b = 2
- if b == 3:
- c = 4
- d = 5
- e = 6
- f = 7
- """)
-
- # Import the python file, executing it.
- coverage.start()
- self.importModule(modname)
- coverage.stop()
- coverage.analysis(modname + ".py")
-
- def testReport(self):
- self.doReportWork("mycode2")
- coverage.report(["mycode2.py"])
- self.assertEqual(self.getStdout(), dedent("""\
- Name Stmts Exec Cover Missing
- ---------------------------------------
- mycode2 7 4 57% 4-6
- """))
-
- def testReportFile(self):
- self.doReportWork("mycode3")
- fout = StringIO()
- coverage.report(["mycode3.py"], file=fout)
- self.assertEqual(self.getStdout(), "")
- self.assertEqual(fout.getvalue(), dedent("""\
- Name Stmts Exec Cover Missing
- ---------------------------------------
- mycode3 7 4 57% 4-6
- """))
-
-
-class AnnotationTests(CoverageTest):
- def testWhite(self):
- self.checkEverything(file='test/white.py', annfile='test/white.py,cover')
-
-
-class CmdLineTests(CoverageTest):
- def help_fn(self, error=None):
- raise Exception(error or "__doc__")
-
- def command_line(self, argv):
- return coverage.CoverageScript().command_line(argv, self.help_fn)
-
- def testHelp(self):
- self.assertRaisesMsg(Exception, "__doc__", self.command_line, ['-h'])
- self.assertRaisesMsg(Exception, "__doc__", self.command_line, ['--help'])
-
- def testUnknownOption(self):
- self.assertRaisesMsg(Exception, "option -z not recognized", self.command_line, ['-z'])
-
- def testBadActionCombinations(self):
- self.assertRaisesMsg(Exception, "You can't specify the 'erase' and 'annotate' options at the same time.", self.command_line, ['-e', '-a'])
- self.assertRaisesMsg(Exception, "You can't specify the 'erase' and 'report' options at the same time.", self.command_line, ['-e', '-r'])
- self.assertRaisesMsg(Exception, "You can't specify the 'erase' and 'combine' options at the same time.", self.command_line, ['-e', '-c'])
- self.assertRaisesMsg(Exception, "You can't specify the 'execute' and 'annotate' options at the same time.", self.command_line, ['-x', '-a'])
- self.assertRaisesMsg(Exception, "You can't specify the 'execute' and 'report' options at the same time.", self.command_line, ['-x', '-r'])
- self.assertRaisesMsg(Exception, "You can't specify the 'execute' and 'combine' options at the same time.", self.command_line, ['-x', '-c'])
-
- def testNeedAction(self):
- self.assertRaisesMsg(Exception, "You must specify at least one of -e, -x, -c, -r, or -a.", self.command_line, ['-p'])
-
- def testArglessActions(self):
- self.assertRaisesMsg(Exception, "Unexpected arguments: foo bar", self.command_line, ['-e', 'foo', 'bar'])
- self.assertRaisesMsg(Exception, "Unexpected arguments: baz quux", self.command_line, ['-c', 'baz', 'quux'])
-
-
-class ProcessTests(CoverageTest):
- def testSaveOnExit(self):
- self.makeFile("mycode", """\
- a = 1
- b = 2
- if b == 3:
- c = 4
- d = 5
- """)
-
- self.assert_(not os.path.exists(".coverage"))
- self.run_command("coverage -x mycode.py")
- self.assert_(os.path.exists(".coverage"))
-
- def testEnvironment(self):
- # Checks that we can import modules from the test directory at all!
- self.makeFile("mycode", """\
- import covmod1
- import covmodzip1
- a = 1
- print 'done'
- """)
-
- self.assert_(not os.path.exists(".coverage"))
- out = self.run_command("coverage -x mycode.py")
- self.assert_(os.path.exists(".coverage"))
- self.assertEqual(out, 'done\n')
-
- def testReport(self):
- self.makeFile("mycode", """\
- import covmod1
- import covmodzip1
- a = 1
- print 'done'
- """)
-
- out = self.run_command("coverage -x mycode.py")
- self.assertEqual(out, 'done\n')
- report1 = self.run_command("coverage -r").replace('\\', '/')
-
- # Name Stmts Exec Cover
- # -----------------------------------------------------------------------
- # c:/ned/coverage/trunk/coverage/__init__ 616 3 0%
- # c:/ned/coverage/trunk/test/modules/covmod1 2 2 100%
- # c:/ned/coverage/trunk/test/zipmods.zip/covmodzip1 2 2 100%
- # c:/python25/lib/atexit 33 5 15%
- # c:/python25/lib/ntpath 250 12 4%
- # c:/python25/lib/threading 562 1 0%
- # mycode 4 4 100%
- # -----------------------------------------------------------------------
- # TOTAL 1467 27 1%
-
- self.assert_("/coverage/" in report1)
- self.assert_("/test/modules/covmod1 " in report1)
- self.assert_("/test/zipmods.zip/covmodzip1 " in report1)
- self.assert_("mycode " in report1)
-
- for l in report1.split('\n'):
- if '/test/modules/covmod1' in l:
- # Save a module prefix for the omit test later.
- prefix = l.split('/test/')[0] + '/test/'
- break
-
- # Try reporting just one module
- report2 = self.run_command("coverage -r mycode.py").replace('\\', '/')
- self.assert_("/coverage/" not in report2)
- self.assert_("/test/modules/covmod1 " not in report2)
- self.assert_("/test/zipmods.zip/covmodzip1 " not in report2)
- self.assert_("mycode " in report2)
-
- # Try reporting while omitting some modules
- report3 = self.run_command("coverage -r -o %s" % prefix).replace('\\', '/')
- self.assert_("/coverage/" in report3)
- self.assert_("/test/modules/covmod1 " not in report3)
- self.assert_("/test/zipmods.zip/covmodzip1 " not in report3)
- self.assert_("mycode " in report3)
-
- def testCombineParallelData(self):
- self.makeFile("b_or_c", """\
- import sys
- a = 1
- if sys.argv[1] == 'b':
- b = 1
- else:
- c = 1
- d = 1
- print 'done'
- """)
-
- out = self.run_command("coverage -x -p b_or_c.py b")
- self.assertEqual(out, 'done\n')
- self.assert_(not os.path.exists(".coverage"))
-
- out = self.run_command("coverage -x -p b_or_c.py c")
- self.assertEqual(out, 'done\n')
- self.assert_(not os.path.exists(".coverage"))
-
- # After two -p runs, there should be two .coverage.machine.123 files.
- self.assertEqual(len([f for f in os.listdir('.') if f.startswith('.coverage.')]), 2)
-
- # Combine the parallel coverage data files into .coverage .
- self.run_command("coverage -c")
- self.assert_(os.path.exists(".coverage"))
-
- # Read the coverage file and see that b_or_c.py has all 7 lines executed.
- data = coverage.CoverageData()
- data.read_file(".coverage")
- self.assertEqual(data.summary()['b_or_c.py'], 7)
-
-
-if __name__ == '__main__':
- print "Testing under Python version: %s" % sys.version
- unittest.main()
-
-
-# TODO: split "and" conditions across lines, and detect not running lines.
-# (Can't be done: trace function doesn't get called for each line
-# in an expression!)
-# TODO: Generator comprehensions?
-# TODO: Constant if tests ("if 1:"). Py 2.4 doesn't execute them.