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