summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.txt1
-rw-r--r--doc/branch.rst92
2 files changed, 79 insertions, 14 deletions
diff --git a/TODO.txt b/TODO.txt
index 8bd2b6f7..a87a9ecd 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -13,6 +13,7 @@ Coverage TODO
(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
diff --git a/doc/branch.rst b/doc/branch.rst
index 5419d1c1..9b03861d 100644
--- a/doc/branch.rst
+++ b/doc/branch.rst
@@ -1,24 +1,88 @@
-Coverage.py now supports branch coverage
+.. _branch:
-- How to use it.
+===========================
+Branch coverage measurement
+===========================
-- Reporting
+Coverage.py now supports branch coverage measurement. Where a line in your
+program could jump to more than one next line, coverage.py 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
-
- - yellow-pink syndrome:
+ def my_partial_fn(x): # line 1
+ if x: # 2
+ y = 10 # 3
+ return y # 4
+
+ my_partial_fn(1)
- Y if never_true:
- P never_executed()
+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.
+
+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 coverage.py with the --branch flag::
+
+ coverage run --branch myprog.py
- - while True is marked as yellow
+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
+exercised.
+
+
+How it works
+------------
- - except ValueError will be marked as yellow if you never see a different exception.
+When measuring branches, coverage.py 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!
+
+
+Problems
+--------
+
+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
-- Exceptions?
+ keep_working() # 6
+
+Because the loop never terminates naturally (jumping from line 1 to 6),
+coverage.py thinks the branch is partially executed.
+
+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
+flagged.
+
- - What should we do with the info about unpredicted arcs?
+Other work
+----------
-- Excluding. Does it 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?