Python coverage.py for total newbies (me!)

I wanted to provide a super simple example of using Ned Batchelder’s coverage.py for testing my Python unittest coverage. The thing that tripped me up at first is that I needed to call coverage.py in such a way to exercise Python’s unittest framework. For example:

coverage run -m unittest discover;
coverage report -m;


-———————————————————————
Ran 3 tests in 0.002s

OK
Name                                          Stmts   Miss  Cover   Missing
-————————————————————————–
init.py                                       0      0   100%
code.py                                           7      0   100%
tests.py                                         11      1    91%   13
-————————————————————————–
TOTAL                                            18      1    94%

I’m stuck on Windows at the moment, and I run these commands from a regular command prompt. These commands invoke Coverage, and the -m option specifies that the unittest module should be loaded (just the same as when you call the python executable itself with the same option).

For reference, here is my example code and tests. I will also show you a mistake I have made and hopefully prevent you from making the same mistake.

class Foo(object):
    def bar(self, x):
        if x % 2:
            return ‘{} even’.format(x)
        else:
            return ‘{} odd’.format(x)

    def baz(self):
        return “Hello, World”

And my tests:

from unittest import TestCase
from my_module import Foo

class FooTests(TestCase):
    def test_one(self):
        self.assertEqual(‘2 odd’, Foo().bar(2))

    def test_two(self):
        self.assertEqual(‘1 even’, Foo().bar(1))

    def test_hello_world(self):
        self.assertEqual(‘Hello, World’, Foo().baz())

    def test_hello_world(self):
        self.assertEqual(‘Hello, World’, Foo().baz())

Can you see my mistake? I have declared a test twice “test_hello_world”. Scroll back up to the output of coverage.py and you’ll see tests.py actually has some missing coverage. Essentially, coverage.py is warning me to go rename or delete my duplicate test.