summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-11-09 08:08:46 -0500
committerNed Batchelder <ned@nedbatchelder.com>2009-11-09 08:08:46 -0500
commit90d80149337a93010e6494122819fe4754f42ec5 (patch)
tree53233bc91e6bb5946ece4146b86632c97541ff2e
parent65f82932eafe64f07fc89ee31b89480db15df367 (diff)
downloadpython-coveragepy-90d80149337a93010e6494122819fe4754f42ec5.tar.gz
Start to document branch coverage
-rw-r--r--doc/branch.rst24
-rw-r--r--doc/branches.py78
2 files changed, 102 insertions, 0 deletions
diff --git a/doc/branch.rst b/doc/branch.rst
new file mode 100644
index 0000000..5419d1c
--- /dev/null
+++ b/doc/branch.rst
@@ -0,0 +1,24 @@
+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?
diff --git a/doc/branches.py b/doc/branches.py
new file mode 100644
index 0000000..1fa705f
--- /dev/null
+++ b/doc/branches.py
@@ -0,0 +1,78 @@
+# 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)