Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create skip_if_no helper function to skip tests when missing a package #2883

Merged
merged 2 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"