1"""
2Generic test utilities.
3
4Based on scipy._libs._testutils
5"""
6
7from __future__ import division, print_function, absolute_import
8
9import os
10import sys
11
12
13__all__ = ["PytestTester"]
14
15
16class PytestTester(object):
17 """
18 Pytest test runner entry point.
19 """
20
21 def __init__(self, module_name):
22 self.module_name = module_name
23
24 def __call__(
25 self,
26 label="fast",
27 verbose=1,
28 extra_argv=None,
29 doctests=False,
30 coverage=False,
31 tests=None,
32 parallel=None,
33 ):
34 import pytest
35
36 module = sys.modules[self.module_name]
37 module_path = os.path.abspath(module.__path__[0])
38
39 pytest_args = ["-l"]
40
41 if doctests:
42 raise ValueError("Doctests not supported")
43
44 if extra_argv:
45 pytest_args += list(extra_argv)
46
47 if verbose and int(verbose) > 1:
48 pytest_args += ["-" + "v" * (int(verbose) - 1)]
49
50 if coverage:
51 pytest_args += ["--cov=" + module_path]
52
53 if label == "fast":
54 pytest_args += ["-m", "not slow"]
55 elif label != "full":
56 pytest_args += ["-m", label]
57
58 if tests is None:
59 tests = [self.module_name]
60
61 if parallel is not None and parallel > 1:
62 if _pytest_has_xdist():
63 pytest_args += ["-n", str(parallel)]
64 else:
65 import warnings
66
67 warnings.warn(
68 "Could not run tests in parallel because "
69 "pytest-xdist plugin is not available."
70 )
71
72 pytest_args += ["--pyargs"] + list(tests)
73
74 try:
75 code = pytest.main(pytest_args)
76 except SystemExit as exc:
77 code = exc.code
78
79 return code == 0
80
81
82def _pytest_has_xdist():
83 """
84 Check if the pytest-xdist plugin is installed, providing parallel tests
85 """
86 # Check xdist exists without importing, otherwise pytests emits warnings
87 from importlib.util import find_spec
88
89 return find_spec("xdist") is not None