From 10ca0a7b37c5a6c52690bac96953d4715197035a Mon Sep 17 00:00:00 2001 From: Hyunsu Cho Date: Fri, 23 Feb 2024 12:46:20 -0800 Subject: [PATCH] Make tests fail gracefully if optional deps are missing --- tests/python/hypothesis_util.py | 1 - tests/python/test_gtil.py | 22 ++++++++++------- tests/python/test_lightgbm_integration.py | 27 ++++++++++---------- tests/python/test_serializer.py | 24 ++++++++++-------- tests/python/test_sklearn_integration.py | 30 ++++++++++++++--------- tests/python/test_xgboost_integration.py | 21 +++++++++------- tests/python/util.py | 3 ++- 7 files changed, 73 insertions(+), 55 deletions(-) diff --git a/tests/python/hypothesis_util.py b/tests/python/hypothesis_util.py index 967bbfd3..359d46dd 100644 --- a/tests/python/hypothesis_util.py +++ b/tests/python/hypothesis_util.py @@ -1,7 +1,6 @@ """Utility functions for hypothesis-based testing""" from math import ceil -from sys import platform as _platform import numpy as np from hypothesis import assume diff --git a/tests/python/test_gtil.py b/tests/python/test_gtil.py index 8be99889..3a3ef82c 100644 --- a/tests/python/test_gtil.py +++ b/tests/python/test_gtil.py @@ -5,25 +5,29 @@ import numpy as np import pytest -from hypothesis import given, settings -from hypothesis.strategies import data as hypothesis_callback -from hypothesis.strategies import integers, just, sampled_from import treelite -from .hypothesis_util import ( - standard_classification_datasets, - standard_regression_datasets, - standard_settings, -) +try: + from hypothesis import given, settings + from hypothesis.strategies import data as hypothesis_callback + from hypothesis.strategies import integers, just, sampled_from +except ImportError: + pytest.skip("hypothesis not installed; skipping", allow_module_level=True) try: import xgboost as xgb except ImportError: - # skip this test suite if XGBoost is not installed pytest.skip("XGBoost not installed; skipping", allow_module_level=True) +from .hypothesis_util import ( + standard_classification_datasets, + standard_regression_datasets, + standard_settings, +) + + @given( predict_kind=sampled_from(["leaf_id", "score_per_tree"]), dataset=standard_regression_datasets(), diff --git a/tests/python/test_lightgbm_integration.py b/tests/python/test_lightgbm_integration.py index 68315072..1a80841f 100644 --- a/tests/python/test_lightgbm_integration.py +++ b/tests/python/test_lightgbm_integration.py @@ -5,33 +5,34 @@ import numpy as np import pytest import scipy -from hypothesis import given, settings -from hypothesis.strategies import data as hypothesis_callback -from hypothesis.strategies import integers, just, sampled_from import treelite -from .hypothesis_util import ( - standard_classification_datasets, - standard_regression_datasets, - standard_settings, -) -from .metadata import dataset_db -from .util import TemporaryDirectory, load_txt, to_categorical +try: + from hypothesis import given, settings + from hypothesis.strategies import data as hypothesis_callback + from hypothesis.strategies import integers, just, sampled_from +except ImportError: + pytest.skip("hypothesis not installed; skipping", allow_module_level=True) try: import lightgbm as lgb except ImportError: - # skip this test suite if LightGBM is not installed pytest.skip("LightGBM not installed; skipping", allow_module_level=True) - try: from sklearn.datasets import load_svmlight_file except ImportError: - # skip this test suite if scikit-learn is not installed pytest.skip("scikit-learn not installed; skipping", allow_module_level=True) +from .hypothesis_util import ( + standard_classification_datasets, + standard_regression_datasets, + standard_settings, +) +from .metadata import dataset_db +from .util import TemporaryDirectory, load_txt, to_categorical + @given( objective=sampled_from(["regression", "regression_l1", "huber"]), diff --git a/tests/python/test_serializer.py b/tests/python/test_serializer.py index 011307c3..cc0d2469 100644 --- a/tests/python/test_serializer.py +++ b/tests/python/test_serializer.py @@ -4,18 +4,15 @@ import numpy as np import pytest -from hypothesis import given, settings -from hypothesis.strategies import data as hypothesis_callback -from hypothesis.strategies import floats, integers, just, sampled_from import treelite -from .hypothesis_util import ( - standard_classification_datasets, - standard_regression_datasets, - standard_settings, -) -from .util import TemporaryDirectory +try: + from hypothesis import given, settings + from hypothesis.strategies import data as hypothesis_callback + from hypothesis.strategies import floats, integers, just, sampled_from +except ImportError: + pytest.skip("hypothesis not installed; skipping", allow_module_level=True) try: from sklearn.dummy import DummyClassifier, DummyRegressor @@ -30,10 +27,17 @@ RandomForestRegressor, ) except ImportError: - # Skip this test suite if scikit-learn is not installed pytest.skip("scikit-learn not installed; skipping", allow_module_level=True) +from .hypothesis_util import ( + standard_classification_datasets, + standard_regression_datasets, + standard_settings, +) +from .util import TemporaryDirectory + + @given( clazz=sampled_from( [ diff --git a/tests/python/test_sklearn_integration.py b/tests/python/test_sklearn_integration.py index 84b01440..ef130c24 100644 --- a/tests/python/test_sklearn_integration.py +++ b/tests/python/test_sklearn_integration.py @@ -1,21 +1,17 @@ """Tests for scikit-learn integration""" import numpy as np -import pandas as pd import pytest -from hypothesis import assume, given, settings -from hypothesis.strategies import data as hypothesis_callback -from hypothesis.strategies import floats, integers, just, sampled_from from packaging.version import parse as parse_version import treelite -from .hypothesis_util import ( - standard_classification_datasets, - standard_regression_datasets, - standard_settings, -) -from .util import has_pandas, to_categorical +try: + from hypothesis import assume, given, settings + from hypothesis.strategies import data as hypothesis_callback + from hypothesis.strategies import floats, integers, just, sampled_from +except ImportError: + pytest.skip("hypothesis not installed; skipping", allow_module_level=True) try: from sklearn import __version__ as sklearn_version @@ -34,10 +30,20 @@ ) from sklearn.utils import shuffle except ImportError: - # Skip this test suite if scikit-learn is not installed pytest.skip("scikit-learn not installed; skipping", allow_module_level=True) -pytestmark = pytest.mark.skipif(not has_pandas(), reason="Pandas required") +try: + import pandas as pd +except ImportError: + pytest.skip("Pandas required", allow_module_level=True) + + +from .hypothesis_util import ( + standard_classification_datasets, + standard_regression_datasets, + standard_settings, +) +from .util import to_categorical @given( diff --git a/tests/python/test_xgboost_integration.py b/tests/python/test_xgboost_integration.py index bec1e188..cd0bc2ba 100644 --- a/tests/python/test_xgboost_integration.py +++ b/tests/python/test_xgboost_integration.py @@ -6,12 +6,21 @@ import numpy as np import pytest -from hypothesis import given, settings -from hypothesis.strategies import data as hypothesis_callback -from hypothesis.strategies import integers, just, lists, sampled_from import treelite +try: + from hypothesis import given, settings + from hypothesis.strategies import data as hypothesis_callback + from hypothesis.strategies import integers, just, lists, sampled_from +except ImportError: + pytest.skip("hypothesis not installed; skipping", allow_module_level=True) + +try: + import xgboost as xgb +except ImportError: + pytest.skip("XGBoost not installed; skipping", allow_module_level=True) + from .hypothesis_util import ( standard_classification_datasets, standard_multi_target_binary_classification_datasets, @@ -20,12 +29,6 @@ ) from .util import TemporaryDirectory, to_categorical -try: - import xgboost as xgb -except ImportError: - # skip this test suite if XGBoost is not installed - pytest.skip("XGBoost not installed; skipping", allow_module_level=True) - def generate_data_for_squared_log_error(n_targets: int = 1): """Generate data containing outliers.""" diff --git a/tests/python/util.py b/tests/python/util.py index 13820b09..f7dc7e8e 100644 --- a/tests/python/util.py +++ b/tests/python/util.py @@ -9,6 +9,7 @@ from typing import Any, Optional, Tuple, Union import numpy as np +import pytest def load_txt(filename): @@ -76,7 +77,7 @@ def to_categorical( Random seed or RandomState object, to control the behavior of randomness """ if not has_pandas(): - raise RuntimeError("Pandas is required for to_categorical()") + pytest.skip(reason="Pandas is required for to_categorical()") import pandas as pd features = features.copy() # Avoid clobbering source matrix