Would like to see list of deselected tests and their node ids in pytest output

Viewed 556

Is there an option to list the deselected tests in the cli output along with the mark that triggered their deselection?

I know that in suites with many tests this would not be good as a default but would be a useful option in something like api testing where the tests are likely to be more limited.

The numeric summary

collected 21 items / 16 deselected / 5 selected 

is helpful but not enough when trying to organize marks and see what happened in a ci build.

1 Answers

pytest has a hookspec pytest_deselected for accessing the deselected tests. Example: add this code to conftest.py in your test root dir:

def pytest_deselected(items):
    if not items:
        return
    config = items[0].session.config
    reporter = config.pluginmanager.getplugin("terminalreporter")
    reporter.ensure_newline()
    for item in items:
        reporter.line(f"deselected: {item.nodeid}", yellow=True, bold=True)

Running the tests now will give you an output similar to this:

$ pytest -vv
...
plugins: cov-2.8.1, asyncio-0.10.0
collecting ...
deselected: test_spam.py::test_spam
deselected: test_spam.py::test_bacon
deselected: test_spam.py::test_ham
collected 4 items / 3 deselected / 1 selected
...

If you want a report in another format, simply store the deselected items in the config and use them for the desired output somewhere else, e.g. pytest_terminal_summary:

# conftest.py

import os

def pytest_deselected(items):
    if not items:
        return
    config = items[0].session.config
    config.deselected = items


def pytest_terminal_summary(terminalreporter, exitstatus, config):
    reports = terminalreporter.getreports('')
    content = os.linesep.join(text for report in reports for secname, text in report.sections)
    deselected = getattr(config, "deselected", [])
    if deselected:
        terminalreporter.ensure_newline()
        terminalreporter.section('Deselected tests', sep='-', yellow=True, bold=True)
        content = os.linesep.join(item.nodeid for item in deselected)
        terminalreporter.line(content)

gives the output:

$ pytest -vv
...
plugins: cov-2.8.1, asyncio-0.10.0
collected 4 items / 3 deselected / 1 selected                                                     

...

---------------------------------------- Deselected tests -----------------------------------------
test_spam.py::test_spam
test_spam.py::test_bacon
test_spam.py::test_ham
================================= 1 passed, 3 deselected in 0.01s =================================
Related