<jupyter_start><jupyter_text>Testing through documentation26.3 doctest — Test interactive Python examples   https://docs.python.org/3/library/doctest.htmldoctest lets you test your code by running examples embedded in the documentation and verifying that they produce the expected results. It works by parsing the help text to find examples, running them, then comparing the output text against the expected value. Many developers find `doctest` **easier** than `unittest` because in its simplest form, there is no API to learn before using it.However, as the examples become more complex **the lack of fixture management** can make writing doctest tests more **cumbersome** than using unittest.  1 Using the command line test runner built into doctest**doctest** looks for `lines` * **beginning** with ：   * **>>>** the `interpreter prompt` to find the beginning of a test case. * **ended** with           * a `blank` line,           * the `next` interpreter prompt.Here, `fun_multiply()` has two examples given in the module: ```doctest_simple.py```<jupyter_code>%%file ./code/doctest/doctest_simple.py

def fun_multiply(a, b):
    """
    >>> fun_multiply(2, 3)
    6
    >>> fun_multiply('a', 3)
    'aaa'
    """
    return a * b<jupyter_output><empty_output><jupyter_text>To **run** the tests, use`doctest` as the `main program` via the **-m** option to the interpreter:```bash>python -m doctest *.py```<jupyter_code>!python -m doctest ./code/doctest/doctest_simple.py<jupyter_output><empty_output><jupyter_text>Usually **no output** is produced .It means **all the examples worked**Pass ** -v ** to the script, and **doctest** prints a detailed log of what it’s trying, and prints a summary at the end:```bash>python -m doctest -v  *.py```<jupyter_code>!python -m doctest -v ./code/doctest/doctest_simple.py<jupyter_output><empty_output><jupyter_text>**Test Examples** cannot usually stand on their own as explanations of a function,**doctest** also lets you keep the **surrounding text** you would normally include in the documentation. **Intervening text** is **ignored**, and can have `any format` as long as it does `not look like a test case`.<jupyter_code>%%file ./code/doctest/doctest_simple_with_docs.py

def fun_multiply(a, b):
    """Returns a * b.

    Works with numbers:
    
    >>> fun_multiply(2, 3)
    6

    and strings:
    
    >>> fun_multiply('a', 3)
    'aaa'
    """
    return a * b

def fun_add(a, b):
    """Returns a + b.

    Works with numbers:
    
    >>> fun_add(2, 3)
    5
    
    and strings:
    
    >>> fun_add('1', '3')
    '13'
    """
    return a + b
!python -m doctest -v ./code/doctest/doctest_simple_with_docs.py<jupyter_output><empty_output><jupyter_text>The surrounding text in the updated `docstring `* **useful to a human reader**,* **ignored by doctest**, the results are the same.  2 Run doctest by calling testmod() at the bottom of modulesThe simplest way to start using doctest  is to **end** each module with:```pythonimport doctestdoctest.testmod()```**doctest** then examines `docstrings` in the module .The module docstring, and all function, class and method docstrings are searched.<jupyter_code>def fun_multiply(a, b):
    """Returns a * b.

    Works with numbers:
    
    >>> fun_multiply(2, 3)
    6

    and strings:
    
    >>> fun_multiply('a', 3)
    'aaa'
    """
    return a * b

def fun_add(a, b):
    """Returns a + b.

    Works with numbers:
    
    >>> fun_add(2, 3)
    5
    
    and strings:
    
    >>> fun_add('1', '3')
    '13'
    """
    return a+b
    #return a + b+1

import doctest
doctest.testmod()
#doctest.testmod(verbose=2)<jupyter_output><empty_output><jupyter_text>Here’s a complete but small example `module`the python code is a module file ,not within a cell of notebook    https://docs.python.org/3.6/library/doctest.html<jupyter_code>%%file ./code/doctest/doctest_example.py
"""
This is the "example" module.

The example module supplies one function, factorial().  For example,

>>> factorial(5)
120
"""

def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    >>> factorial(30.1)
    Traceback (most recent call last):
        ...
    ValueError: n must be exact integer
    >>> factorial(30.0)
    265252859812191058636308480000000

    It must also not be ridiculously large:
    >>> factorial(1e100)
    Traceback (most recent call last):
        ...
    OverflowError: n too large
    """

    import math
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    if n+1 == n:  # catch a value like 1e300
        raise OverflowError("n too large")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result


if __name__ == "__main__":
    import doctest
    doctest.testmod()
    #doctest.testmod(verbose=2)
%run ./code/doctest/doctest_example.py
%run ./code/doctest/doctest_example.py -v<jupyter_output><empty_output><jupyter_text>DocTest of iapws.iapws97https://github.com/jjgomera/iapws<jupyter_code>!pip install iapws<jupyter_output><empty_output><jupyter_text>```python Boundary Region2-Region3def _P23_T(T):    """Define the boundary between Region 2 and 3, P=f(T)    Parameters    ----------    T : float        Temperature [K]    Returns    -------    P : float        Pressure [MPa]    References    ----------    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the    Thermodynamic Properties of Water and Steam August 2007,    http://www.iapws.org/relguide/IF97-Rev.html, Eq 5    Examples    --------    >>> _P23_T(623.15)    16.52916425    """    n = [0.34805185628969e3, -0.11671859879975e1, 0.10192970039326e-2]    return n[0]+n[1]*T+n[2]*T**2```<jupyter_code>from iapws import iapws97

import doctest
doctest.testmod(iapws97)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12603138650703768, 'fraction_numerical': 0.03785795178773661, 'mean_word_length': 3.365819209039548, 'pattern_counts': {'":': 1, '<': 34, '<?xml version=': 0, '>': 96, 'https://': 3, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '221313', 'license': 'MIT', 'n_tokens_mistral': 2213, 'n_tokens_neox': 2022, 'n_words': 645, 'path': 'notebook/Unit6-2-DevTools_doctest.ipynb', 'repo_name': 'alex-treebeard/home', 'size': '6181'}