Coverage for pyquickhelper/ipythonhelper/unittest_notebook.py: 94%
36 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
1"""
2@file
3@brief Functions to test a notebook.
4"""
5import os
6import shutil
7import sys
8from ..loghelper import noLOG
9from .run_notebook import execute_notebook_list, execute_notebook_list_finalize_ut
10from .run_notebook import get_additional_paths as pyq_get_additional_paths
13def test_notebook_execution_coverage(filename, name, folder, this_module_name,
14 valid=None, copy_files=None, modules=None,
15 filter_name=None, fLOG=noLOG):
16 """
17 Runs and tests a specific list of notebooks.
18 The function raises an exception if the execution fails.
20 @param filename test filename (usually ``__file__``)
21 @param name substring to look into notebook filenames
22 @param folder where to look for notebooks
23 @param valid skip cells if valid is False, None for all valid
24 @param copy_files files to copy before running the notebooks.
25 @param modules list of extra dependencies (not installed),
26 example: ``['pyensae']``
27 @param this_module_name the module name being tested (as a string)
28 @param filter_name None or function
29 @param fLOG logging function
31 The function calls @see fn execute_notebook_list_finalize_ut which
32 stores information about the notebooks execution. This will be later
33 used to compute the coverage of notebooks.
34 Modules :epkg:`pyquickhelper` and :epkg:`jyquickhelper` must be
35 imported before calling this function.
36 Example of a unit test calling this function:
38 ::
40 from pyquickhelper.loghelper import fLOG
41 from pyquickhelper.ipythonhelper import test_notebook_execution_coverage
42 from pyquickhelper.pycode import add_missing_development_version
43 import src.mymodule
46 class TestFunctionTestNotebook(unittest.TestCase):
48 def setUp(self):
49 add_missing_development_version(["jyquickhelper"], __file__, hide=True)
51 def test_notebook_example_pyquickhelper(self):
52 fLOG(
53 __file__,
54 self._testMethodName,
55 OutputPrint=__name__ == "__main__")
57 folder = os.path.join(os.path.dirname(__file__), ".." , "..", "_doc", "notebooks")
58 test_notebook_execution_coverage(__file__, "compare_python_distribution",
59 folder, 'mymodule', fLOG=fLOG)
60 """
61 # delayed import (otherwise, it has circular references)
62 from ..pycode import get_temp_folder
64 if filename in (None, ''):
65 raise ValueError( # pragma: no cover
66 "filename cannot be empty.")
67 if not os.path.exists(filename):
68 raise FileNotFoundError( # pragma: no cover
69 f"filename {filename!r} cannot be found.")
70 filename = os.path.abspath(filename)
71 temp = get_temp_folder(filename, f"temp_nb_{name}")
72 doc = os.path.normpath(os.path.join(
73 temp, "..", "..", "..", "_doc", "notebooks", folder))
74 if not os.path.exists(doc):
75 raise FileNotFoundError(doc) # pragma: no cover
76 keepnote = [os.path.join(doc, _) for _ in os.listdir(
77 doc) if name in _ and ".ipynb" in _ and ".ipynb_checkpoints" not in _]
78 if len(keepnote) == 0:
79 raise AssertionError( # pragma: no cover
80 "No found notebook in '{0}'\n{1}".format(
81 doc, "\n".join(os.listdir(doc))))
83 if copy_files is not None:
84 for name_ in copy_files:
85 dest = os.path.join(temp, name_)
86 dest_dir = os.path.dirname(dest)
87 if not os.path.exists(dest_dir):
88 os.mkdir(dest_dir) # pragma: no cover
89 src_file = os.path.join(doc, name_)
90 fLOG(
91 f"[a_test_notebook_runner] copy '{src_file}' to '{dest_dir}'.")
92 shutil.copy(src_file, dest_dir)
94 if 'pyquickhelper' in this_module_name:
95 jyquickhelper = sys.modules['jyquickhelper']
96 if "src." + this_module_name in sys.modules:
97 thismodule = sys.modules["src." + this_module_name]
98 else:
99 thismodule = sys.modules[this_module_name]
100 base = [jyquickhelper, thismodule]
101 else: # pragma: no cover
102 pyquickhelper = sys.modules['pyquickhelper']
103 jyquickhelper = sys.modules['jyquickhelper']
104 if "src." + this_module_name in sys.modules:
105 thismodule = sys.modules["src." + this_module_name]
106 else:
107 thismodule = sys.modules[this_module_name]
108 base = [jyquickhelper, pyquickhelper, thismodule]
110 if modules:
111 base.extend(modules) # pragma: no cover
112 add_path = pyq_get_additional_paths(base)
113 if filter_name:
114 keepnote = [_ for _ in keepnote if filter_name(_)]
115 res = execute_notebook_list(temp, keepnote, additional_path=add_path,
116 valid=valid, fLOG=fLOG)
117 execute_notebook_list_finalize_ut(res, fLOG=fLOG, dump=thismodule)