diff --git a/src/pymatgen/util/testing/__init__.py b/src/pymatgen/util/testing/__init__.py index 9fc69b03004..5abd470b2ed 100644 --- a/src/pymatgen/util/testing/__init__.py +++ b/src/pymatgen/util/testing/__init__.py @@ -10,16 +10,15 @@ import json import pickle # use pickle, not cPickle so that we get the traceback in case of errors import string -import warnings from pathlib import Path from typing import TYPE_CHECKING -from unittest import TestCase import pytest from monty.json import MontyDecoder, MontyEncoder, MSONable from monty.serialization import loadfn from pymatgen.core import ROOT, SETTINGS, Structure +from pymatgen.util.testing._temp_testcase import _TempTestCase4Migrate if TYPE_CHECKING: from collections.abc import Sequence @@ -36,23 +35,12 @@ FAKE_POTCAR_DIR = f"{VASP_IN_DIR}/fake_potcars" -class PymatgenTest(TestCase): +class PymatgenTest(_TempTestCase4Migrate): """Extends unittest.TestCase with several assert methods for array and str comparison.""" # dict of lazily-loaded test structures (initialized to None) TEST_STRUCTURES: ClassVar[dict[str | Path, Structure | None]] = dict.fromkeys(STRUCTURES_DIR.glob("*")) - @classmethod - def setUpClass(cls): - """Issue a FutureWarning, see PR 4209.""" - warnings.warn( - "PymatgenTest is scheduled for migration to pytest after 2026-01-01. " - "Please adapt your tests accordingly.", - FutureWarning, - stacklevel=2, - ) - super().setUpClass() - @pytest.fixture(autouse=True) # make all tests run a in a temporary directory accessible via self.tmp_path def _tmp_dir(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: # https://pytest.org/en/latest/how-to/unittest.html#using-autouse-fixtures-and-accessing-other-fixtures diff --git a/src/pymatgen/util/testing/_temp_testcase.py b/src/pymatgen/util/testing/_temp_testcase.py new file mode 100644 index 00000000000..dd3ddc8ded1 --- /dev/null +++ b/src/pymatgen/util/testing/_temp_testcase.py @@ -0,0 +1,82 @@ +# ruff: noqa: PT009, PT027 + + +from __future__ import annotations + +import warnings +from unittest import TestCase + + +class _TempTestCase4Migrate(TestCase): + """Temporary TestCase for migration to `pytest` framework, + inserted FutureWarning for unittest.TestCase-specific methods. + """ + + def _issue_warning(self, method_name): + warnings.warn( + f"unittest {method_name=} will not be supported by pytest after migration by 2026-01-01, see PR4209.", + FutureWarning, + stacklevel=2, + ) + + def setUp(self, *args, **kwargs): + self._issue_warning("setUp") + super().setUp(*args, **kwargs) + + def tearDown(self, *args, **kwargs): + self._issue_warning("tearDown") + super().tearDown(*args, **kwargs) + + @classmethod + def setUpClass(cls, *args, **kwargs): + cls._issue_warning("setUpClass") + super().setUpClass(*args, **kwargs) + + @classmethod + def tearDownClass(cls, *args, **kwargs): + cls._issue_warning("tearDownClass") + super().tearDownClass(*args, **kwargs) + + def assertEqual(self, *args, **kwargs): + self._issue_warning("assertEqual") + return super().assertEqual(*args, **kwargs) + + def assertNotEqual(self, *args, **kwargs): + self._issue_warning("assertNotEqual") + return super().assertNotEqual(*args, **kwargs) + + def assertTrue(self, *args, **kwargs): + self._issue_warning("assertTrue") + return super().assertTrue(*args, **kwargs) + + def assertFalse(self, *args, **kwargs): + self._issue_warning("assertFalse") + return super().assertFalse(*args, **kwargs) + + def assertIsNone(self, *args, **kwargs): + self._issue_warning("assertIsNone") + return super().assertIsNone(*args, **kwargs) + + def assertIsNotNone(self, *args, **kwargs): + self._issue_warning("assertIsNotNone") + return super().assertIsNotNone(*args, **kwargs) + + def assertIn(self, *args, **kwargs): # codespell:ignore + self._issue_warning("assertIn") # codespell:ignore + return super().assertIn(*args, **kwargs) # codespell:ignore + + def assertNotIn(self, *args, **kwargs): + self._issue_warning("assertNotIn") + return super().assertNotIn(*args, **kwargs) + + def assertIsInstance(self, *args, **kwargs): + self._issue_warning("assertIsInstance") + return super().assertIsInstance(*args, **kwargs) + + def assertNotIsInstance(self, *args, **kwargs): + self._issue_warning("assertNotIsInstance") + return super().assertNotIsInstance(*args, **kwargs) + + def assertRaises(self, *args, **kwargs): + self._issue_warning("assertRaises") + return super().assertRaises(*args, **kwargs)