Craig Gidney
Craig Gidney

Reputation: 18296

Why is doctest skipping tests on imported methods?

I have a python module some_module with an __init__.py file that imports methods, like this:

from .some_python_file import some_method

some_method has a docstring that includes doctests:

def some_method():
    """
    >>> assert False
    """

But when I run doctest on the module, it passes even if the tests should fail.

import some_module
# How do I get this to consistently fail, regardless of whether
# `some_module.some_method` was declared inline or imported?
assert doctest.testmod(some_module).failed == 0

If I instead define some_method within the __init__.py file, the doctest correctly fails.

Why are these two situations behaving differently? The method is present and has the same __doc__ attribute in both cases.

How do I get doctest to run the tests defined in the dostrings of methods that were imported into the module?

Upvotes: 2

Views: 430

Answers (3)

marscher
marscher

Reputation: 830

I stumbled upon this question because I was hacking a __doc__ attribute of an imported object.

from foo import bar
bar.__doc__ = """
>>> assert True
"""

and I was also wondering why the doctest of bar did not get executed by the doctest runner.

The previously given answer to add a `__test__` mapping solved it for good.

```python
__test__ = dict(bar=bar.__doc__)

I think the explanation for this behaviour is the following. If you are using a library, lets say NumPy, you do not want all of their doctests to be collected and run in your own code. Simply, because it would be redundant. You should trust the developers of the library to (continuously) test their code, so you do not have to do it.

If you have tests defined in your own code, you should have a test collector (e.g. pytest) descend into all files of your project structure and run these. You would end up testing all doctests in used libraries, which takes a lot of time. So the decision to ignore imported doctests is very sane.

Upvotes: 0

Mihai
Mihai

Reputation: 991

In Python a module is define by a single file and in your case some_python_file is a module while __init__ is another one. Doctest has a check to run tests only for examples reachable from the module which can be found here.

The best way to see this behaviour in practice is to use PDB and pdb.set_trace() right before you call doctest.testmod(some_module) and step inside to follow the logic.

LE: Doctest ignores imported methods per this comment. If you want to be able to run your test you should probably define a main function in your module and run the test test with python some_module.py. You can follow this example.

To achieve your expected behaviour you need to manually create a __test__ dict in your init file:

from .some_python_file import some_method

__test__ = {"some_method": some_method}

See this link as well.

Upvotes: 2

Moses Koledoye
Moses Koledoye

Reputation: 78554

Objects imported into the module are not searched.

See docs on which docstrings are examined.

You can can inject the imported function into the module's __test__ attribute to have imported objects tested:

__test__ = {'some_method': some_method}

Upvotes: 1

Related Questions