Skip to content

Instantly share code, notes, and snippets.

@althonos
Last active September 8, 2023 09:29
Show Gist options
  • Save althonos/8298af1c707aa596a53a5431bfbd1a0d to your computer and use it in GitHub Desktop.
Save althonos/8298af1c707aa596a53a5431bfbd1a0d to your computer and use it in GitHub Desktop.
Unittest Doctest autoloader: add doctests automatically to the unittest test suites in the tests folder, allowing unit test runners to directly load the doctests.
# coding: utf-8
"""Test doctest contained tests in every file of the module.
"""
import configparser
import doctest
import importlib
import json
import gzip
import os
import pkgutil
import re
import shutil
import sys
import types
import warnings
from unittest import mock
import __mymodule__
def _load_tests_from_module(tests, module, globs, setUp=None, tearDown=None):
"""Load tests from module, iterating through submodules."""
for attr in (getattr(module, x) for x in dir(module) if not x.startswith("_")):
if isinstance(attr, types.ModuleType):
suite = doctest.DocTestSuite(
attr,
globs,
setUp=setUp,
tearDown=tearDown,
optionflags=+doctest.ELLIPSIS,
)
tests.addTests(suite)
return tests
def load_tests(loader, tests, ignore):
"""`load_test` function used by unittest to find the doctests."""
# demonstrate how to load sequences with Biopython without requiring Biopython
def setUp(self):
warnings.simplefilter("ignore")
# ... #
def tearDown(self):
warnings.simplefilter(warnings.defaultaction)
# ... #
# doctests are not compatible with `green`, so we may want to bail out
# early if `green` is running the tests
if sys.argv[0].endswith("green"):
return tests
# recursively traverse all library submodules and load tests from them
packages = [None, __mymodule__]
for pkg in iter(packages.pop, None):
for (_, subpkgname, subispkg) in pkgutil.walk_packages(pkg.__path__):
# do not import __main__ module to avoid side effects!
if subpkgname == "__main__" or subpkgname.startswith("tests") or subpkgname.startswith("cli"):
continue
# import the submodule and add it to the tests
module = importlib.import_module(".".join([pkg.__name__, subpkgname]))
globs = {
# ... #
}
tests.addTests(
doctest.DocTestSuite(
module,
globs=globs,
setUp=setUp,
tearDown=tearDown,
optionflags=+doctest.ELLIPSIS,
)
)
# if the submodule is a package, we need to process its submodules
# as well, so we add it to the package queue
if subispkg:
packages.append(module)
return tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment