Skip to content

Commit 638ce40

Browse files
weiji14seisman
andauthored
Create skip_if_no helper function to skip tests when missing a package (#2883)
Add a helper testing function which returns a pytest.mark.skipif mark that will skip certain unit tests when a package is not installed. This is adapted from pandas' internal skip_if_no function at https://github.com/pandas-dev/pandas/blob/v2.1.4/pandas/util/_test_decorators.py#L121. Added a unit test to ensure that a correct pytest mark is returned. --------- Co-authored-by: Dongdong Tian <[email protected]>
1 parent b0a2c44 commit 638ce40

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

pygmt/helpers/testing.py

+41
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
"""
22
Helper functions for testing.
33
"""
4+
import importlib
45
import inspect
56
import os
67
import string
78

9+
import pytest
810
from pygmt.exceptions import GMTImageComparisonFailure
911
from pygmt.io import load_dataarray
1012
from pygmt.src import which
@@ -237,3 +239,42 @@ def load_static_earth_relief():
237239
"""
238240
fname = which("@static_earth_relief.nc", download="c")
239241
return load_dataarray(fname)
242+
243+
244+
def skip_if_no(package):
245+
"""
246+
Generic function to help skip tests when required packages are not present
247+
on the testing system.
248+
249+
This function returns a pytest mark with a skip condition that will be
250+
evaluated during test collection. An attempt will be made to import the
251+
specified ``package``.
252+
253+
The mark can be used as either a decorator for a test class or to be
254+
applied to parameters in pytest.mark.parametrize calls or parametrized
255+
fixtures. Use pytest.importorskip if an imported moduled is later needed
256+
or for test functions.
257+
258+
If the import is unsuccessful, then the test function (or test case when
259+
used in conjunction with parametrization) will be skipped.
260+
261+
Adapted from
262+
https://github.com/pandas-dev/pandas/blob/v2.1.4/pandas/util/_test_decorators.py#L121
263+
264+
Parameters
265+
----------
266+
package : str
267+
The name of the required package.
268+
269+
Returns
270+
-------
271+
pytest.MarkDecorator
272+
A pytest.mark.skipif to use as either a test decorator or a
273+
parametrization mark.
274+
"""
275+
try:
276+
_ = importlib.import_module(name=package)
277+
has_package = True
278+
except ImportError:
279+
has_package = False
280+
return pytest.mark.skipif(not has_package, reason=f"Could not import '{package}'")

pygmt/tests/test_helpers.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
kwargs_to_strings,
1616
unique_name,
1717
)
18-
from pygmt.helpers.testing import load_static_earth_relief
18+
from pygmt.helpers.testing import load_static_earth_relief, skip_if_no
1919

2020

2121
def test_load_static_earth_relief():
@@ -147,3 +147,19 @@ def test_args_in_kwargs():
147147
# Failing list of arguments
148148
failing_args = ["D", "E", "F"]
149149
assert not args_in_kwargs(args=failing_args, kwargs=kwargs)
150+
151+
152+
def test_skip_if_no():
153+
"""
154+
Test that the skip_if_no helper testing function returns a
155+
pytest.mask.skipif mark decorator.
156+
"""
157+
# Check pytest.mark with a dependency that can be imported
158+
mark_decorator = skip_if_no(package="numpy")
159+
assert mark_decorator.args[0] is False
160+
161+
# Check pytest.mark with a dependency that cannot be imported
162+
mark_decorator = skip_if_no(package="nullpackage")
163+
assert mark_decorator.args[0] is True
164+
assert mark_decorator.kwargs["reason"] == "Could not import 'nullpackage'"
165+
assert mark_decorator.markname == "skipif"

0 commit comments

Comments
 (0)