coverage.py / lab / 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)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.