Description
Execute pytest
without the terminal plugin, i.e. pytest -p no:terminal -s
, when the test contains an assertion failure, for example:
def test_assert():
assert 1 == 2, "fail"
An exception is issued:
(https://github.com/pytest-dev/pytest/blob/main/src/_pytest/assertion/util.py#L161)
_pytest/assertion/__init__.py", line 181, in pytest_assertrepr_compare
return util.assertrepr_compare(config=config, op=op, left=left, right=right)
_pytest/assertion/util.py", line 161, in assertrepr_compare
verbose = config.getoption("verbose")
_pytest/config/__init__.py", line 1484, in getoption
raise ValueError(f"no option named {name!r}") from e
ValueError: no option named 'verbose'
Additional reference to config.option.verbose
: https://github.com/pytest-dev/pytest/blob/main/src/_pytest/assertion/truncate.py#L29
The verbose
parameter is set alongside with the Terminal plugin (https://github.com/pytest-dev/pytest/blob/main/src/_pytest/terminal.py#L144), but apparently is used by the assertion utils as well.
Possible solution, moving verbosity
setting from terminal pytest adoption to runner pytest_adoption , since the verbosity setting affects modules outside the terminal output
Our specific use case: Disable Terminal Plugin and forward results using dedicated logger. We achieve it by implementing the following:
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
result = (yield).get_result()
if call.when == "call" or (call.when == "setup" and call.excinfo is not None):
test_id = None
if callspec := getattr(item, "callspec", None):
test_id = callspec.id
test_details = dict(test_name=item.name, test_id=test_id, passed=result.passed)
if call.excinfo is not None:
test_details.update(dict(type=call.excinfo.type.__name__, reason=str(call.excinfo.value)))
logger.exception("Test failed", extra=test_details, exc_info=call.excinfo.value)
else:
logger.info("Test Passed", extra=test_details)
Then we execute pytest with terminal plugin disabled. The problem occurs upon assertion failures and currently our workaround is setting config.option.verbose
during the the pytest_configure
on our end.