pytest: Deprecation of terminalreporter.writer causes plugin tests to fail.
After the deprecation of terminalreporter.writer
pytest plugin tests using pytester
are getting the deprecation warning, even tho the plugin is not using terminalreporter at all.
Using pytest version 5.3.5 it works as expected.
Tested on both Linux and Mac using the below example test.
pytest_plugins = ("pytester",)
def test_base(testdir, recwarn):
testdir.makepyfile("def test_pass(): pass")
testdir.runpytest()
print(recwarn.list[0])
assert len(recwarn) == 0
assert True
test outcome
# pytest -s -ra -v
=========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.7.6, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 -- /usr/local/bin/python
cachedir: .pytest_cache
rootdir: /pytest-dev/pytest-playground/tests, inifile: pytest.ini
collected 1 item
test_selenium.py::test_base =========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.7.6, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /tmp/pytest-of-root/pytest-5/test_base0
collected 1 item
test_base.py . [100%]
============================================================================================ 1 passed in 0.01s =============================================================================================
{message : PytestDeprecationWarning('TerminalReporter.writer attribute is deprecated, use TerminalReporter._tw instead at your own risk.\nSee https://docs.pytest.org/en/latest/deprecations.html#terminalreporter-writer for more information.'), category : 'PytestDeprecationWarning', filename : '/usr/local/lib/python3.7/site-packages/_pytest/terminal.py', lineno : 289, line : None}
FAILED
================================================================================================= FAILURES =================================================================================================
________________________________________________________________________________________________ test_base _________________________________________________________________________________________________
testdir = <Testdir local('/tmp/pytest-of-root/pytest-5/test_base0')>, recwarn = WarningsRecorder(record=True)
def test_base(testdir, recwarn):
testdir.makepyfile("def test_pass(): pass")
testdir.runpytest()
print(recwarn.list[0])
> assert len(recwarn) == 0
E assert 1 == 0
E +1
E -0
/pytest-dev/pytest-playground/tests/test_selenium.py:10: AssertionError
========================================================================================= short test summary info ==========================================================================================
FAILED test_selenium.py::test_base - assert 1 == 0
============================================================================================ 1 failed in 0.18s =============================================================================================
I’m seeing tests fail in pytest-html which only uses terminalreporter.write_sep()
in a hook, and in pytest-variables which does not use terminalreporter at all.
It’s failing for both python 3.6 and 3.7. Example
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 8
- Comments: 26 (18 by maintainers)
Commits related to this issue
- pin pytest to range pin pytes to range until we deal with this: https://github.com/pytest-dev/pytest/issues/6936 — committed to broadinstitute/viral-core by tomkinsc 4 years ago
- Remove nonrelevant deprecation warning during tests See https://github.com/pytest-dev/pytest/issues/6936 — committed to pytest-dev/pytest-describe by Cito 3 years ago
I’m going to try and get to it this evening
@BeyondEvil it isn’t merged yet, unless I misunderstand.
For reference, the issue is this:
TerminalReporter
has an propertywriter
that has been deprecated in pytest 5.4.0. So every time it is accessed, a deprecation warning is triggered.TerminalReporer
is a plugin. A plugin can define fixtures. During the collection phase, pytest collects fixtures by sifting through all attributes of an object (plugin in this case), accessing them withgetattr
and checking if they are fixtures. If the attribute is a property, its actually runs, and inwriter
s case triggers the warning.What @RonnyPfannschmidt’s change does is: before probing a given attribute, check if it is a property, and if so, skip it. The change itself is small and can be extracted to its own PR. But before we do so, we should check:
I was about to remove this for 6.0, but then thought it was better to just wait to remove this in 6.1: I don’t see much reason to bypass our usual deprecation/removal process.
I agree, but with tongue-in-cheek, I’m sure there’s a test suite out there which has a property, that when accessed, returns a function marked as a fixture. 😆
Atm anything, currently I don’t have much time for pytest due to global reasons
Good reminder, I want that sorted soon
This will be fixed by #6898, which includes a change to skip the
getattr
on properties. Not sure what @RonnyPfannschmidt’s plan is for that PR.