Katie Byers
Katie Byers

Reputation: 1010

How to make python's coverage library include doctests

From googling and experimentation, it seems python's coverage library doesn't include doctests in its calculations. Is there any way to make it do so?

I have searched the docs (https://coverage.readthedocs.io/en/coverage-4.4.1/) and found no mention of doctests, but it seems so odd that it wouldn't have some way of including them that I feel like I must be missing something.

If I'm right and coverage won't include them, how can I get a measurement of my test coverage without changing all my doctests into unit tests with unittest (which I don't want to do)?

Upvotes: 4

Views: 1796

Answers (2)

Raymond Hettinger
Raymond Hettinger

Reputation: 226376

Two ways come to mind, either having the module import itself or loading the module from another module.

Have the module import itself

In file a.py:

def linear(a, b):
    ''' Solve ax + b = 0

        >>> linear(3, 5)
        -1.6666666666666667

    '''
    if a == 0 and b != 0:
        raise ValueError('No solutions')
    return -b  / a

if __name__ == '__main__':
    import doctest
    import a

    print(doctest.testmod(a))

At the command line:

$ coverage run a.py
$ coverage annotate
$ cat a.py,cover

This produces:

> def linear(a, b):
>     ''' Solve ax + b = 0

>         >>> linear(3, 5)
>         -1.6666666666666667

>     '''
>     if a == 0 and b != 0:
!         raise ValueError('No solutions')
>     return -b  / a

> if __name__ == '__main__':
>     import doctest
>     import a

>     print(doctest.testmod(a))

Run the tests from a separate module

Alternatively, you can move the imports and testmod() out of a.py and put them in a separate module.

In file b.py

import doctest
import a

print(doctest.testmod(a))

At the command line:

$ coverage run b.py
$ coverage annotate
$ cat a.py,cover

This produces:

> def linear(a, b):
>     ''' Solve ax + b = 0

>         >>> linear(3, 5)
>         -1.6666666666666667

>     '''
>     if a == 0 and b != 0:
!         raise ValueError('No solutions')
>     return -b  / a

Upvotes: 4

Gribouillis
Gribouillis

Reputation: 2220

A module's doctests can be converted to a unittest's test suite

import mymodule
suite = doctest.DocTestSuite(mymodule)

Upvotes: 0

Related Questions