Commits

Ned Batchelder  committed 346bcfd

Start to document branch coverage

  • Participants
  • Parent commits 8625052

Comments (0)

Files changed (2)

File doc/branch.rst

+Coverage.py now supports branch coverage
+
+- How to use it.
+
+- Reporting
+
+- How it works
+
+- Odd cases
+
+    - yellow-pink syndrome:
+    
+        Y       if never_true:
+        P           never_executed()
+    
+    - while True is marked as yellow
+
+    - except ValueError will be marked as yellow if you never see a different exception.
+    
+- Exceptions?
+
+    - What should we do with the info about unpredicted arcs?
+
+- Excluding. Does it work?

File doc/branches.py

+# Demonstrate some issues with coverage.py branch testing.
+
+def my_function(x):
+    """This isn't real code, just snippets..."""
+    
+    # An infinite loop is structurally still a branch: it can next execute the
+    # first line of the loop, or the first line after the loop.  But
+    # "while True" will never jump to the line after the loop, so the line
+    # is shown as a partial branch:
+
+    i = 0    
+    while True:
+        print "In while True"
+        if i > 0:
+            break
+        i += 1
+    print "Left the True loop"
+    
+    # Notice that "while 1" also has this problem.  Even though the compiler
+    # knows there's no computation at the top of the loop, it's still expressed
+    # in byte code as a branch with two possibilities.
+    
+    i = 0
+    while 1:
+        print "In while 1"
+        if i > 0:
+            break
+        i += 1
+    print "Left the 1 loop"
+    
+    # Coverage.py lets the developer exclude lines that he knows will not be
+    # executed.  So far, the branch coverage doesn't use all that information
+    # when deciding which lines are partially executed.
+    #
+    # Here, even though the else line is explicitly marked as never executed,
+    # the if line complains that it never branched to the else:
+    
+    if x < 1000:
+        # This branch is always taken
+        print "x is reasonable"
+    else:   # pragma: nocover
+        print "this never happens"
+
+    # try-except structures are complex branches.  An except clause with a
+    # type is a three-way branch: there could be no exception, there could be
+    # a matching exception, and there could be a non-matching exception.
+    #
+    # Here we run the code twice: once with no exception, and once with a
+    # matching exception.  The "except" line is marked as partial because we
+    # never executed its third case: a non-matching exception.
+    
+    for y in (1, 2):
+        try:
+            if y % 2:
+                raise ValueError("y is odd!")
+        except ValueError:
+            print "y must have been odd"
+        print "done with y"
+    print "done with 1, 2"
+    
+    # Another except clause, but this time all three cases are executed.  No
+    # partial lines are shown:
+    
+    for y in (0, 1, 2):
+        try:
+            if y % 2:
+                raise ValueError("y is odd!")
+            if y == 0:
+                raise Exception("zero!")
+        except ValueError:
+            print "y must have been odd"
+        except:
+            print "y is something else"
+        print "done with y"
+    print "done with 0, 1, 2"
+
+
+my_function(1)