Ned Batchelder  committed 32da727

Fleshed-out branch documentation.

  • Participants
  • Parent commits fecacc3

Comments (0)

Files changed (2)

     (see top of test_cogapp for examples)
 - Maybe turning off yellow lines should make those lines green?
 - A missing branch to leave the function shows an annotation of -1.
+- XML report needs to get branch information.
 * Speed

File doc/branch.rst now supports branch coverage
+.. _branch:
-- How to use it.
+Branch coverage measurement
-- Reporting now supports branch coverage measurement.  Where a line in your
+program could jump to more than one next line, tracks which of
+those destinations are actually visited, and flags lines that haven't visited
+all of their possible destinations.
-- How it works
+For example::
-- Odd cases
+    def my_partial_fn(x):       # line 1
+        if x:                   #      2
+            y = 10              #      3
+        return y                #      4
+    my_partial_fn(1)
+In this code, the if on line 2 could branch to either line 3 or line 4.
+Statement coverage would show all lines of the function as executed.  But the
+if is always true, so line 2 never jumps to line 4.  In this code, that
+path would cause an error.
-    - yellow-pink syndrome:
+Branch coverage would flag this code as not fully covered because of the
+missing jump from line 2 to line 4.
+How to measure branch coverage
+To measure branch coverage, run with the --branch flag::
+    coverage run --branch
-        Y       if never_true:
-        P           never_executed()
+When you report on the results with "coverage report" or "coverage html", the
+percentage of branch possibilities taken will be included in the percentage
+covered total for each file.  The coverage percentage for a file is the
+actual executions divided by the execution opportunities.  Each line in the
+file is an execution opportunity, as is each branch destination.
+Currently, only HTML reports give information about which lines had missing
+branches.  Lines that were missing some branches are shown in yellow, with an
+annotation at the far right of branch destination line numbers that were not
+How it works
+When measuring branches, collects pairs of line numbers, a source
+and destination for each transition from one line to another.  Static analysis
+of the compiled bytecode provides a list of possible transitions.  Comparing
+the measured to the possible indicates missing branches.
+The idea of tracking how lines follow each other was from C. Titus Brown.
+Thanks, Titus!
+Some Python constructs are difficult to measure properly.  For example, an
+infinite loop will be marked as partially executed::
+    while True:                         # line 1
+        if some_condition():            #      2
+            break                       
+        body_of_loop()                  #      4
-    - while True is marked as yellow
+    keep_working()                      #      6
-    - except ValueError will be marked as yellow if you never see a different exception.
-- Exceptions?
+Because the loop never terminates naturally (jumping from line 1 to 6), thinks the branch is partially executed. 
-    - What should we do with the info about unpredicted arcs?
+Currently, if you exclude code from coverage testing, a branch into that code
+will still be considered executable, and may result in the branch being
-- Excluding. Does it work?
+Other work
+One interesting side effect of tracking line transitions: we know where some
+exceptions happened because a transition happens that wasn't predicted by the
+static analysis.  Currently, I'm not doing anything with this information.
+Any ideas?