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

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 

11 

12 

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. 

19 

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 

30 

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: 

37 

38 :: 

39 

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 

44 

45 

46 class TestFunctionTestNotebook(unittest.TestCase): 

47 

48 def setUp(self): 

49 add_missing_development_version(["jyquickhelper"], __file__, hide=True) 

50 

51 def test_notebook_example_pyquickhelper(self): 

52 fLOG( 

53 __file__, 

54 self._testMethodName, 

55 OutputPrint=__name__ == "__main__") 

56 

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 

63 

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)))) 

82 

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) 

93 

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] 

109 

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)