From 6aff96d31ff496bc755acfd97502ada1385680a2 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Thu, 14 Jan 2021 18:14:39 +0200 Subject: [PATCH] Deprecate raising unittest.SkipTest to skip tests during collection It is not very clear why this code exists -- we are not running any unittest or nose code during collection, and really these frameworks don't have the concept of collection at all, and just raising these exceptions at e.g. the module level would cause an error. So unless I'm missing something, I don't think anyone is using this. Deprecate it so we can eventually clear up this code and keep unittest more tightly restricted to its plugin. --- changelog/TBD.deprecation.rst | 7 +++++++ doc/en/deprecations.rst | 14 ++++++++++++++ src/_pytest/deprecated.py | 5 +++++ src/_pytest/runner.py | 7 +++++++ testing/deprecated_test.py | 17 +++++++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 changelog/TBD.deprecation.rst diff --git a/changelog/TBD.deprecation.rst b/changelog/TBD.deprecation.rst new file mode 100644 index 00000000000..b2e8566eaa9 --- /dev/null +++ b/changelog/TBD.deprecation.rst @@ -0,0 +1,7 @@ +Raising :class:`unittest.SkipTest` to skip collection of tests during the +pytest collection phase is deprecated. Use :func:`pytest.skip` instead. + +Note: This deprecation only relates to using `unittest.SkipTest` during test +collection. You are probably not doing that. Ordinary usage of +:class:`unittest.SkipTest` / :meth:`unittest.TestCase.skipTest` / +:func:`unittest.skip` in unittest test cases is fully supported. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index ec2397e596f..0dcbd8ceb36 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -18,6 +18,20 @@ Deprecated Features Below is a complete list of all pytest features which are considered deprecated. Using those features will issue :class:`PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters `. +Raising ``unittest.SkipTest`` during collection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. deprecated:: 6.3 + +Raising :class:`unittest.SkipTest` to skip collection of tests during the +pytest collection phase is deprecated. Use :func:`pytest.skip` instead. + +Note: This deprecation only relates to using `unittest.SkipTest` during test +collection. You are probably not doing that. Ordinary usage of +:class:`unittest.SkipTest` / :meth:`unittest.TestCase.skipTest` / +:func:`unittest.skip` in unittest test cases is fully supported. + + The ``--strict`` command-line option ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 19b31d66538..fa91f909769 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -64,6 +64,11 @@ PRIVATE = PytestDeprecationWarning("A private pytest class or function was used.") +UNITTEST_SKIP_DURING_COLLECTION = PytestDeprecationWarning( + "Raising unittest.SkipTest to skip tests during collection is deprecated. " + "Use pytest.skip() instead." +) + # You want to make some `__init__` or function "private". # diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index df046a78aca..844e41f8057 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -2,6 +2,7 @@ import bdb import os import sys +import warnings from typing import Callable from typing import cast from typing import Dict @@ -27,6 +28,7 @@ from _pytest.compat import final from _pytest.config.argparsing import Parser from _pytest.deprecated import check_ispytest +from _pytest.deprecated import UNITTEST_SKIP_DURING_COLLECTION from _pytest.nodes import Collector from _pytest.nodes import Item from _pytest.nodes import Node @@ -374,6 +376,11 @@ def pytest_make_collect_report(collector: Collector) -> CollectReport: # Type ignored because unittest is loaded dynamically. skip_exceptions.append(unittest.SkipTest) # type: ignore if isinstance(call.excinfo.value, tuple(skip_exceptions)): + if unittest is not None and isinstance( + call.excinfo.value, unittest.SkipTest # type: ignore[attr-defined] + ): + warnings.warn(UNITTEST_SKIP_DURING_COLLECTION, stacklevel=2) + outcome = "skipped" r_ = collector._repr_failure_py(call.excinfo, "line") assert isinstance(r_, ExceptionChainRepr), repr(r_) diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index 6d92d181f99..18300f62a1a 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -136,3 +136,20 @@ def __init__(self, foo: int, *, _ispytest: bool = False) -> None: # Doesn't warn. PrivateInit(10, _ispytest=True) + + +def test_raising_unittest_skiptest_during_collection_is_deprecated( + pytester: Pytester, +) -> None: + pytester.makepyfile( + """ + import unittest + raise unittest.SkipTest() + """ + ) + result = pytester.runpytest() + result.stdout.fnmatch_lines( + [ + "*PytestDeprecationWarning: Raising unittest.SkipTest*", + ] + )