1.. _deprecations: 2 3Deprecations and Removals 4========================= 5 6This page lists all pytest features that are currently deprecated or have been removed in past major releases. 7The objective is to give users a clear rationale why a certain feature has been removed, and what alternatives 8should be used instead. 9 10.. contents:: 11 :depth: 3 12 :local: 13 14 15Deprecated Features 16------------------- 17 18Below is a complete list of all pytest features which are considered deprecated. Using those features will issue 19:class:`PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters <warnings>`. 20 21 22The ``pytest_warning_captured`` hook 23~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 25.. deprecated:: 6.0 26 27This hook has an `item` parameter which cannot be serialized by ``pytest-xdist``. 28 29Use the ``pytest_warning_recored`` hook instead, which replaces the ``item`` parameter 30by a ``nodeid`` parameter. 31 32The ``pytest.collect`` module 33~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 34 35.. deprecated:: 6.0 36 37The ``pytest.collect`` module is no longer part of the public API, all its names 38should now be imported from ``pytest`` directly instead. 39 40 41The ``pytest._fillfuncargs`` function 42~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43 44.. deprecated:: 6.0 45 46This function was kept for backward compatibility with an older plugin. 47 48It's functionality is not meant to be used directly, but if you must replace 49it, use `function._request._fillfixtures()` instead, though note this is not 50a public API and may break in the future. 51 52 53Removed Features 54---------------- 55 56As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after 57an appropriate period of deprecation has passed. 58 59``--no-print-logs`` command-line option 60~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 61 62.. deprecated:: 5.4 63.. versionremoved:: 6.0 64 65 66The ``--no-print-logs`` option and ``log_print`` ini setting are removed. If 67you used them, please use ``--show-capture`` instead. 68 69A ``--show-capture`` command-line option was added in ``pytest 3.5.0`` which allows to specify how to 70display captured output when tests fail: ``no``, ``stdout``, ``stderr``, ``log`` or ``all`` (the default). 71 72 73 74Result log (``--result-log``) 75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 76 77.. deprecated:: 4.0 78.. versionremoved:: 6.0 79 80The ``--result-log`` option produces a stream of test reports which can be 81analysed at runtime, but it uses a custom format which requires users to implement their own 82parser. 83 84The `pytest-reportlog <https://github.com/pytest-dev/pytest-reportlog>`__ plugin provides a ``--report-log`` option, a more standard and extensible alternative, producing 85one JSON object per-line, and should cover the same use cases. Please try it out and provide feedback. 86 87The ``pytest-reportlog`` plugin might even be merged into the core 88at some point, depending on the plans for the plugins and number of users using it. 89 90``pytest_collect_directory`` hook 91~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 92 93.. versionremoved:: 6.0 94 95The ``pytest_collect_directory`` has not worked properly for years (it was called 96but the results were ignored). Users may consider using :func:`pytest_collection_modifyitems <_pytest.hookspec.pytest_collection_modifyitems>` instead. 97 98TerminalReporter.writer 99~~~~~~~~~~~~~~~~~~~~~~~ 100 101.. versionremoved:: 6.0 102 103The ``TerminalReporter.writer`` attribute has been deprecated and should no longer be used. This 104was inadvertently exposed as part of the public API of that plugin and ties it too much 105with ``py.io.TerminalWriter``. 106 107Plugins that used ``TerminalReporter.writer`` directly should instead use ``TerminalReporter`` 108methods that provide the same functionality. 109 110``junit_family`` default value change to "xunit2" 111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 112 113.. versionchanged:: 6.0 114 115The default value of ``junit_family`` option will change to ``xunit2`` in pytest 6.0, which 116is an update of the old ``xunit1`` format and is supported by default in modern tools 117that manipulate this type of file (for example, Jenkins, Azure Pipelines, etc.). 118 119Users are recommended to try the new ``xunit2`` format and see if their tooling that consumes the JUnit 120XML file supports it. 121 122To use the new format, update your ``pytest.ini``: 123 124.. code-block:: ini 125 126 [pytest] 127 junit_family=xunit2 128 129If you discover that your tooling does not support the new format, and want to keep using the 130legacy version, set the option to ``legacy`` instead: 131 132.. code-block:: ini 133 134 [pytest] 135 junit_family=legacy 136 137By using ``legacy`` you will keep using the legacy/xunit1 format when upgrading to 138pytest 6.0, where the default format will be ``xunit2``. 139 140In order to let users know about the transition, pytest will issue a warning in case 141the ``--junitxml`` option is given in the command line but ``junit_family`` is not explicitly 142configured in ``pytest.ini``. 143 144Services known to support the ``xunit2`` format: 145 146* `Jenkins <https://www.jenkins.io/>`__ with the `JUnit <https://plugins.jenkins.io/junit>`__ plugin. 147* `Azure Pipelines <https://azure.microsoft.com/en-us/services/devops/pipelines>`__. 148 149Node Construction changed to ``Node.from_parent`` 150~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 151 152.. versionchanged:: 6.0 153 154The construction of nodes now should use the named constructor ``from_parent``. 155This limitation in api surface intends to enable better/simpler refactoring of the collection tree. 156 157This means that instead of :code:`MyItem(name="foo", parent=collector, obj=42)` 158one now has to invoke :code:`MyItem.from_parent(collector, name="foo")`. 159 160Plugins that wish to support older versions of pytest and suppress the warning can use 161`hasattr` to check if `from_parent` exists in that version: 162 163.. code-block:: python 164 165 def pytest_pycollect_makeitem(collector, name, obj): 166 if hasattr(MyItem, "from_parent"): 167 item = MyItem.from_parent(collector, name="foo") 168 item.obj = 42 169 return item 170 else: 171 return MyItem(name="foo", parent=collector, obj=42) 172 173Note that ``from_parent`` should only be called with keyword arguments for the parameters. 174 175 176``pytest.fixture`` arguments are keyword only 177~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 178 179.. versionremoved:: 6.0 180 181Passing arguments to pytest.fixture() as positional arguments has been removed - pass them by keyword instead. 182 183``funcargnames`` alias for ``fixturenames`` 184~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 186.. versionremoved:: 6.0 187 188The ``FixtureRequest``, ``Metafunc``, and ``Function`` classes track the names of 189their associated fixtures, with the aptly-named ``fixturenames`` attribute. 190 191Prior to pytest 2.3, this attribute was named ``funcargnames``, and we have kept 192that as an alias since. It is finally due for removal, as it is often confusing 193in places where we or plugin authors must distinguish between fixture names and 194names supplied by non-fixture things such as ``pytest.mark.parametrize``. 195 196 197``pytest.config`` global 198~~~~~~~~~~~~~~~~~~~~~~~~ 199 200.. versionremoved:: 5.0 201 202The ``pytest.config`` global object is deprecated. Instead use 203``request.config`` (via the ``request`` fixture) or if you are a plugin author 204use the ``pytest_configure(config)`` hook. Note that many hooks can also access 205the ``config`` object indirectly, through ``session.config`` or ``item.config`` for example. 206 207 208.. _`raises message deprecated`: 209 210``"message"`` parameter of ``pytest.raises`` 211~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 212 213.. versionremoved:: 5.0 214 215It is a common mistake to think this parameter will match the exception message, while in fact 216it only serves to provide a custom message in case the ``pytest.raises`` check fails. To prevent 217users from making this mistake, and because it is believed to be little used, pytest is 218deprecating it without providing an alternative for the moment. 219 220If you have a valid use case for this parameter, consider that to obtain the same results 221you can just call ``pytest.fail`` manually at the end of the ``with`` statement. 222 223For example: 224 225.. code-block:: python 226 227 with pytest.raises(TimeoutError, message="Client got unexpected message"): 228 wait_for(websocket.recv(), 0.5) 229 230 231Becomes: 232 233.. code-block:: python 234 235 with pytest.raises(TimeoutError): 236 wait_for(websocket.recv(), 0.5) 237 pytest.fail("Client got unexpected message") 238 239 240If you still have concerns about this deprecation and future removal, please comment on 241`issue #3974 <https://github.com/pytest-dev/pytest/issues/3974>`__. 242 243 244.. _raises-warns-exec: 245 246``raises`` / ``warns`` with a string as the second argument 247~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 248 249.. versionremoved:: 5.0 250 251Use the context manager form of these instead. When necessary, invoke ``exec`` 252directly. 253 254Example: 255 256.. code-block:: python 257 258 pytest.raises(ZeroDivisionError, "1 / 0") 259 pytest.raises(SyntaxError, "a $ b") 260 261 pytest.warns(DeprecationWarning, "my_function()") 262 pytest.warns(SyntaxWarning, "assert(1, 2)") 263 264Becomes: 265 266.. code-block:: python 267 268 with pytest.raises(ZeroDivisionError): 269 1 / 0 270 with pytest.raises(SyntaxError): 271 exec("a $ b") # exec is required for invalid syntax 272 273 with pytest.warns(DeprecationWarning): 274 my_function() 275 with pytest.warns(SyntaxWarning): 276 exec("assert(1, 2)") # exec is used to avoid a top-level warning 277 278 279 280 281Using ``Class`` in custom Collectors 282~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 283 284.. versionremoved:: 4.0 285 286Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector`` 287subclasses has been deprecated. Users instead should use ``pytest_pycollect_makeitem`` to customize node types during 288collection. 289 290This issue should affect only advanced plugins who create new collection types, so if you see this warning 291message please contact the authors so they can change the code. 292 293 294marks in ``pytest.mark.parametrize`` 295~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 296 297.. versionremoved:: 4.0 298 299Applying marks to values of a ``pytest.mark.parametrize`` call is now deprecated. For example: 300 301.. code-block:: python 302 303 @pytest.mark.parametrize( 304 "a, b", 305 [ 306 (3, 9), 307 pytest.mark.xfail(reason="flaky")(6, 36), 308 (10, 100), 309 (20, 200), 310 (40, 400), 311 (50, 500), 312 ], 313 ) 314 def test_foo(a, b): 315 ... 316 317This code applies the ``pytest.mark.xfail(reason="flaky")`` mark to the ``(6, 36)`` value of the above parametrization 318call. 319 320This was considered hard to read and understand, and also its implementation presented problems to the code preventing 321further internal improvements in the marks architecture. 322 323To update the code, use ``pytest.param``: 324 325.. code-block:: python 326 327 @pytest.mark.parametrize( 328 "a, b", 329 [ 330 (3, 9), 331 pytest.param(6, 36, marks=pytest.mark.xfail(reason="flaky")), 332 (10, 100), 333 (20, 200), 334 (40, 400), 335 (50, 500), 336 ], 337 ) 338 def test_foo(a, b): 339 ... 340 341 342``pytest_funcarg__`` prefix 343~~~~~~~~~~~~~~~~~~~~~~~~~~~ 344 345.. versionremoved:: 4.0 346 347In very early pytest versions fixtures could be defined using the ``pytest_funcarg__`` prefix: 348 349.. code-block:: python 350 351 def pytest_funcarg__data(): 352 return SomeData() 353 354Switch over to the ``@pytest.fixture`` decorator: 355 356.. code-block:: python 357 358 @pytest.fixture 359 def data(): 360 return SomeData() 361 362 363 364[pytest] section in setup.cfg files 365~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 367.. versionremoved:: 4.0 368 369``[pytest]`` sections in ``setup.cfg`` files should now be named ``[tool:pytest]`` 370to avoid conflicts with other distutils commands. 371 372 373Metafunc.addcall 374~~~~~~~~~~~~~~~~ 375 376.. versionremoved:: 4.0 377 378``_pytest.python.Metafunc.addcall`` was a precursor to the current parametrized mechanism. Users should use 379:meth:`_pytest.python.Metafunc.parametrize` instead. 380 381Example: 382 383.. code-block:: python 384 385 def pytest_generate_tests(metafunc): 386 metafunc.addcall({"i": 1}, id="1") 387 metafunc.addcall({"i": 2}, id="2") 388 389Becomes: 390 391.. code-block:: python 392 393 def pytest_generate_tests(metafunc): 394 metafunc.parametrize("i", [1, 2], ids=["1", "2"]) 395 396 397``cached_setup`` 398~~~~~~~~~~~~~~~~ 399 400.. versionremoved:: 4.0 401 402``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures. 403 404Example: 405 406.. code-block:: python 407 408 @pytest.fixture 409 def db_session(): 410 return request.cached_setup( 411 setup=Session.create, teardown=lambda session: session.close(), scope="module" 412 ) 413 414This should be updated to make use of standard fixture mechanisms: 415 416.. code-block:: python 417 418 @pytest.fixture(scope="module") 419 def db_session(): 420 session = Session.create() 421 yield session 422 session.close() 423 424 425You can consult `funcarg comparison section in the docs <https://docs.pytest.org/en/stable/funcarg_compare.html>`_ for 426more information. 427 428 429pytest_plugins in non-top-level conftest files 430~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 431 432.. versionremoved:: 4.0 433 434Defining :globalvar:`pytest_plugins` is now deprecated in non-top-level conftest.py 435files because they will activate referenced plugins *globally*, which is surprising because for all other pytest 436features ``conftest.py`` files are only *active* for tests at or below it. 437 438 439``Config.warn`` and ``Node.warn`` 440~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 441 442.. versionremoved:: 4.0 443 444Those methods were part of the internal pytest warnings system, but since ``3.8`` pytest is using the builtin warning 445system for its own warnings, so those two functions are now deprecated. 446 447``Config.warn`` should be replaced by calls to the standard ``warnings.warn``, example: 448 449.. code-block:: python 450 451 config.warn("C1", "some warning") 452 453Becomes: 454 455.. code-block:: python 456 457 warnings.warn(pytest.PytestWarning("some warning")) 458 459``Node.warn`` now supports two signatures: 460 461* ``node.warn(PytestWarning("some message"))``: is now the **recommended** way to call this function. 462 The warning instance must be a PytestWarning or subclass. 463 464* ``node.warn("CI", "some message")``: this code/message form has been **removed** and should be converted to the warning instance form above. 465 466record_xml_property 467~~~~~~~~~~~~~~~~~~~ 468 469.. versionremoved:: 4.0 470 471The ``record_xml_property`` fixture is now deprecated in favor of the more generic ``record_property``, which 472can be used by other consumers (for example ``pytest-html``) to obtain custom information about the test run. 473 474This is just a matter of renaming the fixture as the API is the same: 475 476.. code-block:: python 477 478 def test_foo(record_xml_property): 479 ... 480 481Change to: 482 483.. code-block:: python 484 485 def test_foo(record_property): 486 ... 487 488 489Passing command-line string to ``pytest.main()`` 490~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 492.. versionremoved:: 4.0 493 494Passing a command-line string to ``pytest.main()`` is deprecated: 495 496.. code-block:: python 497 498 pytest.main("-v -s") 499 500Pass a list instead: 501 502.. code-block:: python 503 504 pytest.main(["-v", "-s"]) 505 506 507By passing a string, users expect that pytest will interpret that command-line using the shell rules they are working 508on (for example ``bash`` or ``Powershell``), but this is very hard/impossible to do in a portable way. 509 510 511Calling fixtures directly 512~~~~~~~~~~~~~~~~~~~~~~~~~ 513 514.. versionremoved:: 4.0 515 516Calling a fixture function directly, as opposed to request them in a test function, is deprecated. 517 518For example: 519 520.. code-block:: python 521 522 @pytest.fixture 523 def cell(): 524 return ... 525 526 527 @pytest.fixture 528 def full_cell(): 529 cell = cell() 530 cell.make_full() 531 return cell 532 533This is a great source of confusion to new users, which will often call the fixture functions and request them from test functions interchangeably, which breaks the fixture resolution model. 534 535In those cases just request the function directly in the dependent fixture: 536 537.. code-block:: python 538 539 @pytest.fixture 540 def cell(): 541 return ... 542 543 544 @pytest.fixture 545 def full_cell(cell): 546 cell.make_full() 547 return cell 548 549Alternatively if the fixture function is called multiple times inside a test (making it hard to apply the above pattern) or 550if you would like to make minimal changes to the code, you can create a fixture which calls the original function together 551with the ``name`` parameter: 552 553.. code-block:: python 554 555 def cell(): 556 return ... 557 558 559 @pytest.fixture(name="cell") 560 def cell_fixture(): 561 return cell() 562 563 564``yield`` tests 565~~~~~~~~~~~~~~~ 566 567.. versionremoved:: 4.0 568 569pytest supported ``yield``-style tests, where a test function actually ``yield`` functions and values 570that are then turned into proper test methods. Example: 571 572.. code-block:: python 573 574 def check(x, y): 575 assert x ** x == y 576 577 578 def test_squared(): 579 yield check, 2, 4 580 yield check, 3, 9 581 582This would result into two actual test functions being generated. 583 584This form of test function doesn't support fixtures properly, and users should switch to ``pytest.mark.parametrize``: 585 586.. code-block:: python 587 588 @pytest.mark.parametrize("x, y", [(2, 4), (3, 9)]) 589 def test_squared(x, y): 590 assert x ** x == y 591 592Internal classes accessed through ``Node`` 593~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 594 595.. versionremoved:: 4.0 596 597Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances now issue 598this warning: 599 600.. code-block:: text 601 602 usage of Function.Module is deprecated, please use pytest.Module instead 603 604Users should just ``import pytest`` and access those objects using the ``pytest`` module. 605 606This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings. 607 608``Node.get_marker`` 609~~~~~~~~~~~~~~~~~~~ 610 611.. versionremoved:: 4.0 612 613As part of a large :ref:`marker-revamp`, ``_pytest.nodes.Node.get_marker`` is removed. See 614:ref:`the documentation <update marker code>` on tips on how to update your code. 615 616 617``somefunction.markname`` 618~~~~~~~~~~~~~~~~~~~~~~~~~ 619 620.. versionremoved:: 4.0 621 622As part of a large :ref:`marker-revamp` we already deprecated using ``MarkInfo`` 623the only correct way to get markers of an element is via ``node.iter_markers(name)``. 624 625 626``pytest_namespace`` 627~~~~~~~~~~~~~~~~~~~~ 628 629.. versionremoved:: 4.0 630 631This hook is deprecated because it greatly complicates the pytest internals regarding configuration and initialization, making some 632bug fixes and refactorings impossible. 633 634Example of usage: 635 636.. code-block:: python 637 638 class MySymbol: 639 ... 640 641 642 def pytest_namespace(): 643 return {"my_symbol": MySymbol()} 644 645 646Plugin authors relying on this hook should instead require that users now import the plugin modules directly (with an appropriate public API). 647 648As a stopgap measure, plugin authors may still inject their names into pytest's namespace, usually during ``pytest_configure``: 649 650.. code-block:: python 651 652 import pytest 653 654 655 def pytest_configure(): 656 pytest.my_symbol = MySymbol() 657