Pytest - 如何使 class 夹具打印出现在控制台中第一个 test0 行文本之前

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

我想知道是否有办法让 pytest 在第一个测试行之前打印出 class 夹具内的打印调用。让我展示一个脚本、控制台结果和所需控制台的基本示例:

test.py 文件

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

控制台

============================= 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

想要的控制台

============================= 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

这是一个愚蠢的请求,但如果有人知道“解决”这个问题的方法,我会洗耳恭听。提前致谢:)

我能想到的唯一方法是使用 pytest_collection_finish 挂钩。此挂钩在主测试循环 运行.

之前调用

如果有多个具有设置方法的测试,此解决方案可能无法按预期工作,因此您可能需要将此测试与以下挂钩放在其自己的子目录中。这是说明 here in the documentation.

话虽如此,如果您将以下挂钩放入各自的 conftest.py 文件中:

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()

然后 运行 测试给了我:

======================================= 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 =========================================