Python tutorials > Testing > Doctests > How to run doctests?
How to run doctests?
Understanding and Running Doctests in Python
Doctests are a simple way to test your Python code by embedding test cases directly within your docstrings. This tutorial explains how to run doctests and interpret their results.
Basic Doctest Structure
A doctest is a snippet of Python code embedded in a docstring. The code is preceded by >>>
, and the expected output immediately follows on the next line(s). The add
function above includes two doctests.
def add(a, b):
"""Return the sum of a and b.
>>> add(2, 3)
5
>>> add(-1, 1)
0
"""
return a + b
Running Doctests from the Command Line
The most straightforward way to run doctests is from the command line. Replace your_module.py
with the name of the Python file containing the doctests. The -m doctest
option tells Python to run the doctest
module.
python -m doctest your_module.py
Running Doctests within a Python Script
You can also run doctests within a Python script. The doctest.testmod()
function automatically finds and executes all doctests in the specified module. Make sure to replace your_module
with the actual name of your module.
import doctest
import your_module # Replace with your module name
if __name__ == "__main__":
doctest.testmod(your_module)
Interpreting Doctest Results
When you run doctests, the output will indicate whether the tests passed or failed. If all tests pass, you'll see a message similar to: If a test fails, you'll see a detailed error message showing the expected and actual output.Trying
add(2, 3)
Expecting:
5
ok
Trying
add(-1, 1)
Expecting:
0
ok
1 items had no tests:
__main__
1 items passed all tests:
2 tests in __main__.add
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
Concepts Behind the Snippet
Doctests leverage the Python interpreter to execute code snippets found in docstrings. The doctest
module parses these snippets, runs them, and compares the actual output with the expected output specified in the docstring. This provides a simple, integrated way to verify that your code behaves as documented.
Real-Life Use Case
Imagine you're building a complex mathematical library. You can use doctests to verify that each function produces the correct results for various inputs. This allows you to quickly identify and fix bugs as you develop the library. For instance, consider a function for calculating the factorial of a number. You can include doctests that cover cases like factorial(0), factorial(1), and factorial(5) to ensure the function behaves correctly for edge cases and typical inputs.
Best Practices
Interview Tip
When discussing testing in Python interviews, mentioning doctests showcases your awareness of built-in testing tools. Highlight their simplicity and ease of integration into your workflow. Be prepared to explain the advantages and disadvantages of using doctests compared to more advanced testing frameworks like pytest
or unittest
.
When to Use Them
Doctests are ideal for: They are less suitable for complex testing scenarios that require setup, teardown, or mocking.
Memory Footprint
Doctests generally have a minimal memory footprint. They only require the resources needed to execute the code snippets and compare the output. The impact on memory usage is usually negligible, especially for small and focused tests.
Alternatives
Alternatives to doctests include:
Pros
Cons
FAQ
-
How do I handle floating-point numbers in doctests?
Floating-point numbers can be tricky due to their inherent imprecision. Use the
round()
function to compare results to a certain number of decimal places. Alternatively, you can use an approximate comparison using a tolerance value. -
Can I ignore certain lines in the output during doctest comparison?
Yes, you can use the
doctest.ELLIPSIS
option to ignore parts of the output. This is useful when the output contains dynamic content like memory addresses or timestamps.For example:
>>> import datetime >>> print(datetime.datetime.now()) 2023-10-27 10:00:00.123456 >>> # doctest: +ELLIPSIS ...
-
How do I test functions that raise exceptions?
You can use the
doctest.IGNORE_EXCEPTION_DETAIL
option to match the exception type without matching the exception message. Also, usingassertRaises
context manager withunittest
in a doctest can be useful, although it can make them less readable.Example:
>>> def divide(a, b): ... if b == 0: ... raise ValueError("Cannot divide by zero") ... return a / b >>> divide(10, 0) Traceback (most recent call last): ... ValueError: Cannot divide by zero