Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a list of TestReports at the end of a py.test run?

Tags:

python

pytest

I want to get a list of all tests (e.g. in the form of a py.test TestReport) at the end of all tests.

I know that pytest_runtest_makereportdoes something similar, but only for a single test. But I want to implement a hook or something in conftest.py to process the whole list of tests before the py.test application terminates.

Is there a way to do this?

like image 956
Alex Avatar asked Mar 23 '18 08:03

Alex


People also ask

Which command can be used to show all available fixtures?

Additionally, if you wish to display a list of fixtures for each test, try the --fixtures-per-test flag.

Which pytest option is used to filter test cases by pattern in test case names?

pytest -k <pattern> allows a single pattern. One option is to have a pytest. mark against each test, but my requirement is to run different combination of tests from different files.

What is the name of the directory that pytest will look at to detect tests?

In the selected directories, pytest looks for test_*. py or *_test.py files.


1 Answers

Here an example which can help you. Structure of files:

/example:
   __init__.py  # empty file
   /test_pack_1
      __init__.py # empty file
      conftest.py # pytest hooks
      test_my.py  # a few tests for demonstration

There are 2 tests in test_my.py:

def test_one():
    assert 1 == 1
    print('1==1')


def test_two():
    assert 1 == 2
    print('1!=2')

Example of conftest.py:

import pytest
from _pytest.runner import TestReport
from _pytest.terminal import TerminalReporter


@pytest.hookimpl(hookwrapper=True)
def pytest_terminal_summary(terminalreporter):  # type: (TerminalReporter) -> generator
    yield
    # you can do here anything - I just print report info
    print('*' * 8 + 'HERE CUSTOM LOGIC' + '*' * 8)

    for failed in terminalreporter.stats.get('failed', []):  # type: TestReport
        print('failed! node_id:%s, duration: %s, details: %s' % (failed.nodeid,
                                                                 failed.duration,
                                                                 str(failed.longrepr)))

    for passed in terminalreporter.stats.get('passed', []):  # type: TestReport
        print('passed! node_id:%s, duration: %s, details: %s' % (passed.nodeid,
                                                                 passed.duration,
                                                                 str(passed.longrepr)))

Documentation says that pytest_terminal_summary has exitstatus arg

Run tests without any additional options: py.test ./example. Example of output:

example/test_pack_1/test_my.py .F
********HERE CUSTOM LOGIC********
failed! node_id:test_pack_1/test_my.py::test_two, duration: 0.000385999679565, details: def test_two():
>       assert 1 == 2
E       assert 1 == 2

example/test_pack_1/test_my.py:7: AssertionError
passed! node_id:test_pack_1/test_my.py::test_one, duration: 0.00019907951355, details: None

=================================== FAILURES ===================================
___________________________________ test_two ___________________________________

    def test_two():
>       assert 1 == 2
E       assert 1 == 2

example/test_pack_1/test_my.py:7: AssertionError
====================== 1 failed, 1 passed in 0.01 seconds ======================

Hope this helps.

Note! Make sure that .pyc files was removed before running tests

like image 134
Danila Ganchar Avatar answered Nov 02 '22 10:11

Danila Ganchar