diff --git a/docs/reference/changelog.md b/docs/reference/changelog.md index 7c103af0..869812eb 100644 --- a/docs/reference/changelog.md +++ b/docs/reference/changelog.md @@ -8,6 +8,7 @@ Unreleased changes ### CI/CD - Review the coverage configuration in light of `covdefaults`, adopting its `assert_never` exclusion and `skip_covered` report setting, and raising all package coverage gates to 100% ({gh-pr}`390`) +- Adopt pytest's strict mode, following the recommendations from pytest's "Good Integration Practices" guide ({gh-pr}`387`) - Make the e2e path sanity check independent of the checkout directory's name, so tests can run from git worktrees ({gh-pr}`391`) - Bump actions/download-artifact from 7 to 8 ({gh-pr}`368`) - Bump actions/upload-artifact from 6 to 7 ({gh-pr}`369`) diff --git a/pytest.ini b/pytest.ini index 28f12a98..13abb1ba 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,19 +1,17 @@ [pytest] addopts = # Tests summary report - # ref: https://docs.pytest.org/en/8.3.x/how-to/output.html#producing-a-detailed-summary-report + # ref: https://docs.pytest.org/en/stable/how-to/output.html#producing-a-detailed-summary-report -ra # (V)Verbose -vv # Show local variables in tracebacks --showlocals - # Raise error on unknown markers - --strict-markers # Import mode - # ref: https://docs.pytest.org/en/8.3.x/explanation/pythonpath.html#import-modes + # ref: https://docs.pytest.org/en/stable/explanation/pythonpath.html#import-modes --import-mode=importlib # Minimal duration in seconds for inclusion in slowest list - # ref: https://docs.pytest.org/en/8.3.x/how-to/usage.html#profiling-test-execution-duration + # ref: https://docs.pytest.org/en/stable/how-to/usage.html#profiling-test-execution-duration --durations-min=0.5 # Fail if a test tries to open a network connection # ref: https://github.com/miketheman/pytest-socket @@ -25,22 +23,25 @@ addopts = --no-cov-on-fail --cov-report=term-missing +# Enable all of pytest's strictness options (requires pytest>=9). +# As of pytest 9.1, this enables: strict_config, strict_markers, +# strict_parametrization_ids, and strict_xfail. Any new strictness +# options added in future pytest releases will also be picked up here. +# ref: https://docs.pytest.org/en/stable/explanation/goodpractices.html#using-pytest-s-strict-mode +# ref: https://docs.pytest.org/en/stable/reference/reference.html#confval-strict +strict = true + # Default list of directories that pytest will search for tests in. # This should be overridden in tox.ini to run specific test suites. -# https://docs.pytest.org/en/8.3.x/reference/reference.html#confval-testpaths +# https://docs.pytest.org/en/stable/reference/reference.html#confval-testpaths testpaths = tests # List of directories that should be added to the python search path -# https://docs.pytest.org/en/8.3.x/reference/reference.html#confval-pythonpath +# https://docs.pytest.org/en/stable/reference/reference.html#confval-pythonpath pythonpath = cicd_utils -# Tests marked with @pytest.mark.xfail that actually -# succeed will by default fail the test suite. -# https://docs.pytest.org/en/8.3.x/reference/reference.html#confval-xfail_strict -xfail_strict = true - # Warning filters pattern: action:message:category:module:line -# ref: https://docs.pytest.org/en/8.3.x/how-to/capture-warnings.html +# ref: https://docs.pytest.org/en/stable/how-to/capture-warnings.html # ref: https://docs.python.org/3/library/warnings.html#describing-warning-filters # ref: https://docs.python.org/3/using/cmdline.html#cmdoption-W filterwarnings = diff --git a/requirements/tests.txt b/requirements/tests.txt index 49ba62cb..686fc433 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -1,5 +1,6 @@ # pytest and plugins -pytest +# (pytest>=9 is needed for the `strict` config option set in pytest.ini) +pytest>=9 pytest-icdiff pytest-socket diff --git a/tests/unit/test_hist.py b/tests/unit/test_hist.py index 0008bbbe..f7c3d00f 100644 --- a/tests/unit/test_hist.py +++ b/tests/unit/test_hist.py @@ -39,7 +39,11 @@ def test_bin_trace_samples_nbins(nbins: int) -> None: assert len(density_trace) == nbins -@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")]) +@pytest.mark.parametrize( + "non_finite_value", + [np.inf, np.nan, float("inf"), float("nan")], + ids=["np-inf", "np-nan", "float-inf", "float-nan"], +) def test_bin_trace_samples_fails_for_non_finite_values(non_finite_value: float) -> None: err_msg = "The samples array should not contain any infs or NaNs." with pytest.raises(ValueError, match=err_msg): @@ -64,7 +68,11 @@ def test_bin_trace_samples_weights_not_same_length() -> None: bin_trace_samples(trace_samples=SAMPLES_IN, nbins=NBINS, weights=[1, 1, 1]) -@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")]) +@pytest.mark.parametrize( + "non_finite_value", + [np.inf, np.nan, float("inf"), float("nan")], + ids=["np-inf", "np-nan", "float-inf", "float-nan"], +) def test_bin_trace_samples_weights_fails_for_non_finite_values( non_finite_value: float, ) -> None: diff --git a/tests/unit/test_kde.py b/tests/unit/test_kde.py index cd6c0b58..a2fe0ba8 100644 --- a/tests/unit/test_kde.py +++ b/tests/unit/test_kde.py @@ -49,7 +49,11 @@ def test_estimate_density_trace_points() -> None: assert np.argmin(y) == 0 -@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")]) +@pytest.mark.parametrize( + "non_finite_value", + [np.inf, np.nan, float("inf"), float("nan")], + ids=["np-inf", "np-nan", "float-inf", "float-nan"], +) def test_estimate_density_trace_fails_for_non_finite_values(non_finite_value: float) -> None: err_msg = "The samples array should not contain any infs or NaNs." with pytest.raises(ValueError, match=err_msg): @@ -101,7 +105,11 @@ def test_estimate_density_trace_weights_not_same_length() -> None: ) -@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")]) +@pytest.mark.parametrize( + "non_finite_value", + [np.inf, np.nan, float("inf"), float("nan")], + ids=["np-inf", "np-nan", "float-inf", "float-nan"], +) def test_estimate_density_trace_weights_fails_for_non_finite_values( non_finite_value: float, ) -> None: diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index cf35a97e..33092628 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -44,7 +44,7 @@ def test_raise_for_non_2d_array(self) -> None: @pytest.mark.parametrize( ("densities_type", "rows_type"), - product((id_func, tuple, list), (id_func, tuple, list, np.asarray)), + list(product((id_func, tuple, list), (id_func, tuple, list, np.asarray))), ) def test_expected_output( self,