Search code examples
python-3.xloggingpytestfixtures

Pytest - How to make the class fixture prints appear before the first test0 line text in the console


I was wondering if there is anyway to make that pytest prints out the print calls inside a class fixture before the first test line. Let me show an basic example of script, console result and desired console:

test.py file

import pytest

class TestApp:

  @pytest.fixture(scope="class",autouse=True)
  def setup_class(self):
    print("\nSetting things up")

  @pytest.mark.paratrize("n1,n2,expected", [(2,3,5), (4,5,9), (6,7,13)])
  def test_add(self, n1, n2, expected):
    assert n1+n2 == expected

console

============================= test session starts ==============================
platform linux -- Python 3.7.10, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /test, configfile: pytest.ini
collected 3 items

test.py::TestApp::test_add[test0] 
Setting things up
PASSED
test.py::TestApp::test_add[test1] PASSED
test.py::TestApp::test_add[test2] PASSED

desired console

============================= test session starts ==============================
platform linux -- Python 3.7.10, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /test, configfile: pytest.ini
collected 3 items

Setting things up
test.py::TestApp::test_add[test0] PASSED
test.py::TestApp::test_add[test1] PASSED
test.py::TestApp::test_add[test2] PASSED

It's a silly request but if someone know a way to "fix" this I'm all ears. Thanks in advance :)


Solution

  • The only way I can think of doing this is using the pytest_collection_finish hook. This hook is called prior to main test loop running.

    This solution might not work as intended if there are multiple tests that have setup methods so you might need to place this test with the following hook in its own sub-directory. This is illustrated here in the documentation.

    With that being said if you place the following hook in your respective conftest.py file:

    def pytest_collection_finish(session):
        # grab all the test nodes that will be run
        items = session.items
        # grab the first test in the loop
        first = items[0]
        # call the `setup` method on it prior to the main test loop starting
        first.setup()
    

    And then running the tests gives me:

    ======================================= test session starts ========================================
    platform darwin -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
    cachedir: .pytest_cache
    rootdir: *****
    collected 3 items                                                                                  
    
    Setting things up
    
    test_foo.py::TestApp::test_add[2-3-5] PASSED
    test_foo.py::TestApp::test_add[4-5-9] PASSED
    test_foo.py::TestApp::test_add[6-7-13] PASSED
    
    ======================================== 3 passed in 0.01s =========================================