Skip to content

Commit

Permalink
Create skip_if_no helper function to skip tests when missing a package (
Browse files Browse the repository at this point in the history
#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]>
  • Loading branch information
weiji14 and seisman committed Dec 16, 2023
1 parent b0a2c44 commit 638ce40
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
41 changes: 41 additions & 0 deletions pygmt/helpers/testing.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""
Helper functions for testing.
"""
import importlib
import inspect
import os
import string

import pytest
from pygmt.exceptions import GMTImageComparisonFailure
from pygmt.io import load_dataarray
from pygmt.src import which
Expand Down Expand Up @@ -237,3 +239,42 @@ def load_static_earth_relief():
"""
fname = which("@static_earth_relief.nc", download="c")
return load_dataarray(fname)


def skip_if_no(package):
"""
Generic function to help skip tests when required packages are not present
on the testing system.
This function returns a pytest mark with a skip condition that will be
evaluated during test collection. An attempt will be made to import the
specified ``package``.
The mark can be used as either a decorator for a test class or to be
applied to parameters in pytest.mark.parametrize calls or parametrized
fixtures. Use pytest.importorskip if an imported moduled is later needed
or for test functions.
If the import is unsuccessful, then the test function (or test case when
used in conjunction with parametrization) will be skipped.
Adapted from
https://github.com/pandas-dev/pandas/blob/v2.1.4/pandas/util/_test_decorators.py#L121
Parameters
----------
package : str
The name of the required package.
Returns
-------
pytest.MarkDecorator
A pytest.mark.skipif to use as either a test decorator or a
parametrization mark.
"""
try:
_ = importlib.import_module(name=package)
has_package = True
except ImportError:
has_package = False
return pytest.mark.skipif(not has_package, reason=f"Could not import '{package}'")
18 changes: 17 additions & 1 deletion pygmt/tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
kwargs_to_strings,
unique_name,
)
from pygmt.helpers.testing import load_static_earth_relief
from pygmt.helpers.testing import load_static_earth_relief, skip_if_no


def test_load_static_earth_relief():
Expand Down Expand Up @@ -147,3 +147,19 @@ def test_args_in_kwargs():
# Failing list of arguments
failing_args = ["D", "E", "F"]
assert not args_in_kwargs(args=failing_args, kwargs=kwargs)


def test_skip_if_no():
"""
Test that the skip_if_no helper testing function returns a
pytest.mask.skipif mark decorator.
"""
# Check pytest.mark with a dependency that can be imported
mark_decorator = skip_if_no(package="numpy")
assert mark_decorator.args[0] is False

# Check pytest.mark with a dependency that cannot be imported
mark_decorator = skip_if_no(package="nullpackage")
assert mark_decorator.args[0] is True
assert mark_decorator.kwargs["reason"] == "Could not import 'nullpackage'"
assert mark_decorator.markname == "skipif"

0 comments on commit 638ce40

Please sign in to comment.