Aluode/PerceptionLabPortable
0
1"""
2Pytest test running.
3
4This module implements the ``test()`` function for NumPy modules. The usual
5boiler plate for doing that is to put the following in the module
6``__init__.py`` file::
7
8 from pywt._pytesttester import PytestTester
9 test = PytestTester(__name__).test
10 del PytestTester
11
12
13Warnings filtering and other runtime settings should be dealt with in the
14``pytest.ini`` file in the pywt repo root. The behavior of the test depends on
15whether or not that file is found as follows:
16
17* ``pytest.ini`` is present (develop mode)
18 All warnings except those explicily filtered out are raised as error.
19* ``pytest.ini`` is absent (release mode)
20 DeprecationWarnings and PendingDeprecationWarnings are ignored, other
21 warnings are passed through.
22
23In practice, tests run from the PyWavelets repo are run in develop mode. That
24includes the standard ``python runtests.py`` invocation.
25
26"""
27
28import os
29import sys
30
31__all__ = ['PytestTester']
32
33
34def _show_pywt_info():
35 import pywt
36 from pywt._c99_config import _have_c99_complex
37 print(f"PyWavelets version {pywt.__version__}")
38 if _have_c99_complex:
39 print("Compiled with C99 complex support.")
40 else:
41 print("Compiled without C99 complex support.")
42
43
44class PytestTester:
45 """
46 Pytest test runner.
47
48 This class is made available in ``pywt.testing``, and a test function
49 is typically added to a package's __init__.py like so::
50
51 from pywt.testing import PytestTester
52 test = PytestTester(__name__).test
53 del PytestTester
54
55 Calling this test function finds and runs all tests associated with the
56 module and all its sub-modules.
57
58 Attributes
59 ----------
60 module_name : str
61 Full path to the package to test.
62
63 Parameters
64 ----------
65 module_name : module name
66 The name of the module to test.
67
68 """
69 def __init__(self, module_name):
70 self.module_name = module_name
71
72 def __call__(self, label='fast', verbose=1, extra_argv=None,
73 doctests=False, coverage=False, durations=-1, tests=None):
74 """
75 Run tests for module using pytest.
76
77 Parameters
78 ----------
79 label : {'fast', 'full'}, optional
80 Identifies the tests to run. When set to 'fast', tests decorated
81 with `pytest.mark.slow` are skipped, when 'full', the slow marker
82 is ignored.
83 verbose : int, optional
84 Verbosity value for test outputs, in the range 1-3. Default is 1.
85 extra_argv : list, optional
86 List with any extra arguments to pass to pytests.
87 doctests : bool, optional
88 .. note:: Not supported
89 coverage : bool, optional
90 If True, report coverage of NumPy code. Default is False.
91 Requires installation of (pip) pytest-cov.
92 durations : int, optional
93 If < 0, do nothing, If 0, report time of all tests, if > 0,
94 report the time of the slowest `timer` tests. Default is -1.
95 tests : test or list of tests
96 Tests to be executed with pytest '--pyargs'
97
98 Returns
99 -------
100 result : bool
101 Return True on success, false otherwise.
102
103 Examples
104 --------
105 >>> result = np.lib.test() #doctest: +SKIP
106 ...
107 1023 passed, 2 skipped, 6 deselected, 1 xfailed in 10.39 seconds
108 >>> result
109 True
110
111 """
112 import pytest
113
114 module = sys.modules[self.module_name]
115 module_path = os.path.abspath(module.__path__[0])
116
117 # setup the pytest arguments
118 pytest_args = ["-l"]
119
120 # offset verbosity. The "-q" cancels a "-v".
121 pytest_args += ["-q"]
122
123 # Filter out annoying import messages. Want these in both develop and
124 # release mode.
125 pytest_args += [
126 "-W ignore:Not importing directory",
127 "-W ignore:numpy.dtype size changed",
128 "-W ignore:numpy.ufunc size changed", ]
129
130 if doctests:
131 raise ValueError("Doctests not supported")
132
133 if extra_argv:
134 pytest_args += list(extra_argv)
135
136 if verbose > 1:
137 pytest_args += ["-" + "v"*(verbose - 1)]
138
139 if coverage:
140 pytest_args += ["--cov=" + module_path]
141
142 if label == "fast":
143 pytest_args += ["-m", "not slow"]
144 elif label != "full":
145 pytest_args += ["-m", label]
146
147 if durations >= 0:
148 pytest_args += [f"--durations={durations}"]
149
150 if tests is None:
151 tests = [self.module_name]
152
153 pytest_args += ["--pyargs"] + list(tests)
154
155 # run tests.
156 _show_pywt_info()
157
158 try:
159 code = pytest.main(pytest_args)
160 except SystemExit as exc:
161 code = exc.code
162
163 return code == 0
164 