diff --git a/.azure-pipelines/azure-pipelines-base.yml b/.azure-pipelines/azure-pipelines-base.yml index b7a2ba1ed9..888801a3a7 100644 --- a/.azure-pipelines/azure-pipelines-base.yml +++ b/.azure-pipelines/azure-pipelines-base.yml @@ -5,8 +5,6 @@ jobs: variables: - name: NUMBA_DISABLE_JIT value: 1 - - name: ARVIZ_CI_MACHINE - value: 1 timeoutInMinutes: 360 strategy: matrix: @@ -82,9 +80,15 @@ jobs: python -m pip freeze displayName: 'Print packages' + - script: | + ARVIZ_REQUIRE_ALL_DEPS=TRUE python -m pytest arviz/tests/base_tests --cov arviz --cov-report=xml + condition: and(succeeded(), eq(variables.OptionalRequirements, true)) + displayName: 'pytest (require all dependencies)' + - script: | python -m pytest arviz/tests/base_tests --cov arviz --cov-report=xml - displayName: 'pytest' + condition: and(succeeded(), eq(variables.OptionalRequirements, false)) + displayName: 'pytest (skip if dependency missing)' - script: | ls -ahl diff --git a/.azure-pipelines/azure-pipelines-external.yml b/.azure-pipelines/azure-pipelines-external.yml index b255ee8898..138ff80223 100644 --- a/.azure-pipelines/azure-pipelines-external.yml +++ b/.azure-pipelines/azure-pipelines-external.yml @@ -5,7 +5,7 @@ jobs: variables: - name: NUMBA_DISABLE_JIT value: 1 - - name: ARVIZ_CI_MACHINE + - name: ARVIZ_REQUIRE_ALL_DEPS value: 1 timeoutInMinutes: 360 strategy: diff --git a/arviz/tests/base_tests/test_data.py b/arviz/tests/base_tests/test_data.py index bb1882059e..55882b81aa 100644 --- a/arviz/tests/base_tests/test_data.py +++ b/arviz/tests/base_tests/test_data.py @@ -42,7 +42,6 @@ draws, eight_schools_params, models, - running_on_ci, ) @@ -1469,7 +1468,7 @@ def test_json_converters(self, models): @pytest.mark.skipif( - not (importlib.util.find_spec("datatree") or running_on_ci()), + not (importlib.util.find_spec("datatree") or "ARVIZ_REQUIRE_ALL_DEPS" in os.environ), reason="test requires xarray-datatree library", ) class TestDataTree: diff --git a/arviz/tests/base_tests/test_data_zarr.py b/arviz/tests/base_tests/test_data_zarr.py index 53144ad3d8..c93b0253dd 100644 --- a/arviz/tests/base_tests/test_data_zarr.py +++ b/arviz/tests/base_tests/test_data_zarr.py @@ -16,7 +16,6 @@ draws, eight_schools_params, importorskip, - running_on_ci, ) zarr = importorskip("zarr") # pylint: disable=invalid-name diff --git a/arviz/tests/base_tests/test_diagnostics_numba.py b/arviz/tests/base_tests/test_diagnostics_numba.py index e3da38ded5..5de10f716d 100644 --- a/arviz/tests/base_tests/test_diagnostics_numba.py +++ b/arviz/tests/base_tests/test_diagnostics_numba.py @@ -1,7 +1,4 @@ """Test Diagnostic methods""" - -import importlib - # pylint: disable=redefined-outer-name, no-member, too-many-public-methods import numpy as np import pytest @@ -11,13 +8,10 @@ from ...stats import bfmi, mcse, rhat from ...stats.diagnostics import _mc_error, ks_summary from ...utils import Numba -from ..helpers import running_on_ci +from ..helpers import importorskip from .test_diagnostics import data # pylint: disable=unused-import -pytestmark = pytest.mark.skipif( # pylint: disable=invalid-name - (importlib.util.find_spec("numba") is None) and not running_on_ci(), - reason="test requires numba which is not installed", -) +importorskip("numba") rcParams["data.load"] = "eager" diff --git a/arviz/tests/base_tests/test_plot_utils.py b/arviz/tests/base_tests/test_plot_utils.py index 55d0224f3b..471bd91f27 100644 --- a/arviz/tests/base_tests/test_plot_utils.py +++ b/arviz/tests/base_tests/test_plot_utils.py @@ -1,5 +1,6 @@ # pylint: disable=redefined-outer-name import importlib +import os import numpy as np import pytest @@ -20,10 +21,10 @@ from ...sel_utils import xarray_sel_iter, xarray_to_ndarray from ...stats.density_utils import get_bins from ...utils import get_coords -from ..helpers import running_on_ci # Check if Bokeh is installed bokeh_installed = importlib.util.find_spec("bokeh") is not None # pylint: disable=invalid-name +skip_tests = (not bokeh_installed) and ("ARVIZ_REQUIRE_ALL_DEPS" not in os.environ) @pytest.mark.parametrize( @@ -212,10 +213,7 @@ def test_filter_plotter_list_warning(): assert len(plotters_filtered) == 5 -@pytest.mark.skipif( - not (bokeh_installed or running_on_ci()), - reason="test requires bokeh which is not installed", -) +@pytest.mark.skipif(skip_tests, reason="test requires bokeh which is not installed") def test_bokeh_import(): """Tests that correct method is returned on bokeh import""" plot = get_plotting_function("plot_dist", "distplot", "bokeh") @@ -290,10 +288,7 @@ def test_mpl_dealiase_sel_kwargs(): assert res["line_color"] == "red" -@pytest.mark.skipif( - not (bokeh_installed or running_on_ci()), - reason="test requires bokeh which is not installed", -) +@pytest.mark.skipif(skip_tests, reason="test requires bokeh which is not installed") def test_bokeh_dealiase_sel_kwargs(): """Check bokeh dealiase_sel_kwargs behaviour. @@ -315,10 +310,7 @@ def test_bokeh_dealiase_sel_kwargs(): assert res["line_color"] == "red" -@pytest.mark.skipif( - not (bokeh_installed or running_on_ci()), - reason="test requires bokeh which is not installed", -) +@pytest.mark.skipif(skip_tests, reason="test requires bokeh which is not installed") def test_set_bokeh_circular_ticks_labels(): """Assert the axes returned after placing ticks and tick labels for circular plots.""" import bokeh.plotting as bkp diff --git a/arviz/tests/base_tests/test_stats_numba.py b/arviz/tests/base_tests/test_stats_numba.py index d6d63f3fc8..8b76bde113 100644 --- a/arviz/tests/base_tests/test_stats_numba.py +++ b/arviz/tests/base_tests/test_stats_numba.py @@ -1,6 +1,4 @@ # pylint: disable=redefined-outer-name, no-member -import importlib - import numpy as np import pytest @@ -9,15 +7,12 @@ from ...utils import Numba from ..helpers import ( # pylint: disable=unused-import check_multiple_attrs, + importorskip, multidim_models, - running_on_ci, ) from .test_stats import centered_eight, non_centered_eight # pylint: disable=unused-import -pytestmark = pytest.mark.skipif( # pylint: disable=invalid-name - (importlib.util.find_spec("numba") is None) and not running_on_ci(), - reason="test requires numba which is not installed", -) +numba = importorskip("numba") rcParams["data.load"] = "eager" diff --git a/arviz/tests/base_tests/test_utils_numba.py b/arviz/tests/base_tests/test_utils_numba.py index c3d1f252ed..7a64944bfd 100644 --- a/arviz/tests/base_tests/test_utils_numba.py +++ b/arviz/tests/base_tests/test_utils_numba.py @@ -8,14 +8,10 @@ from ...stats.stats_utils import stats_variance_2d as svar from ...utils import Numba, _numba_var, numba_check -from ..helpers import running_on_ci +from ..helpers import importorskip from .test_utils import utils_with_numba_import_fail # pylint: disable=unused-import -pytestmark = pytest.mark.skipif( # pylint: disable=invalid-name - (importlib.util.find_spec("numba") is None) and not running_on_ci(), - reason="test requires numba which is not installed", -) - +importorskip("numba") def test_utils_fixture(utils_with_numba_import_fail): """Test of utils fixture to ensure mock is applied correctly""" diff --git a/arviz/tests/external_tests/test_data_pystan.py b/arviz/tests/external_tests/test_data_pystan.py index 2be52c8fd4..42dca1fe1b 100644 --- a/arviz/tests/external_tests/test_data_pystan.py +++ b/arviz/tests/external_tests/test_data_pystan.py @@ -1,6 +1,7 @@ # pylint: disable=no-member, invalid-name, redefined-outer-name, too-many-function-args import importlib from collections import OrderedDict +import os import numpy as np import pytest @@ -16,19 +17,18 @@ importorskip, load_cached_models, pystan_version, - running_on_ci, ) # Check if either pystan or pystan3 is installed pystan_installed = (importlib.util.find_spec("pystan") is not None) or ( importlib.util.find_spec("stan") is not None ) -pytestmark = pytest.mark.skipif( - not (pystan_installed | running_on_ci()), - reason="test requires pystan/pystan3 which is not installed", -) +@pytest.mark.skipif( + not (pystan_installed or "ARVIZ_REQUIRE_ALL_DEPS" in os.environ), + reason="test requires pystan/pystan3 which is not installed" +) class TestDataPyStan: @pytest.fixture(scope="class") def data(self, eight_schools_params, draws, chains): diff --git a/arviz/tests/helpers.py b/arviz/tests/helpers.py index 15dbd95689..3e826b8587 100644 --- a/arviz/tests/helpers.py +++ b/arviz/tests/helpers.py @@ -620,11 +620,6 @@ def test_precompile_models(eight_schools_params, draws, chains): load_cached_models(eight_schools_params, draws, chains) -def running_on_ci() -> bool: - """Return True if running on CI machine.""" - return os.environ.get("ARVIZ_CI_MACHINE") is not None - - def importorskip( modname: str, minversion: Optional[str] = None, reason: Optional[str] = None ) -> Any: @@ -643,9 +638,9 @@ def importorskip( Example:: docutils = pytest.importorskip("docutils") """ - # ARVIZ_CI_MACHINE is True if tests run on CI, where ARVIZ_CI_MACHINE env variable exists - ARVIZ_CI_MACHINE = running_on_ci() - if not ARVIZ_CI_MACHINE: + # Unless ARVIZ_REQUIRE_ALL_DEPS is defined, tests that require a missing dependency are skipped + # if set, missing optional dependencies trigger failed tests. + if "ARVIZ_REQUIRE_ALL_DEPS" not in os.environ: return pytest.importorskip(modname=modname, minversion=minversion, reason=reason) import warnings