如何标记一个函数不是 pytest 的测试?

How to mark one function not a test for pytest?

我正在使用 pytest 测试一些基于 TensorFlow 的代码。

A TestCase 为简单起见定义如下:

class TestCase(tf.test.TestCase):
    # ...

问题是 tf.test.TestCase 提供了一个有用的函数 self.test_session(),它在 pytest 中被视为一个测试方法,因为它的名称以 test_.

开头

由于 test_session() 方法,结果 pytest 报告比我定义的测试方法更多的成功测试。

我用下面的代码跳过test_session:

class TestCase(tf.test.TestCase):
    @pytest.mark.skip
    @contextmanager
    def test_session(self):
        with super().test_session() as sess:
            yield sess

但是在测试报告中会有一些"s"表明有一些跳过测试。

我是否可以在不全局更改 pytest 测试发现规则的情况下将一种确切的方法标记为不是测试方法?

在单元测试中有办法做到这一点

@unittest.skip("skipping reason")

tf.test 有 skipTest(reason) 在 https://www.tensorflow.org/api_docs/python/tf/test/TestCase#skipTest

阅读更多

在收集测试项目后过滤掉误报:使用自定义 post-collection hook 在您的测试目录中创建一个 conftest.py

# conftest.py
def pytest_collection_modifyitems(session, config, items):
    items[:] = [item for item in items if item.name != 'test_session']

pytest 仍将收集 test_session 方法(您会在 pytest 报告行 collected n tests 中注意到),但不会将它们作为测试执行并且不会考虑他们在测试中的任何地方 运行.


相关:修复 unittest 式测试

查看

您可以直接设置 __test__ = False,也可以通过编写一个简单的装饰器来设置。后者的行为应该类似于 Nose 的 nottest 装饰器。

def nottest(obj):
    obj.__test__ = False
    return obj

class TestMyTest:

    def test_should_not_collect_1(self):
        assert False
    test_should_not_collect_1.__test__ = False

    @nottest
    def test_should_not_collect_2(self):
        assert False

    def test_should_collect(self):
        assert True


def test_should_not_collect_1():
    assert False
test_should_not_collect_1.__test__ = False

@nottest
def test_should_not_collect_2():
    assert False


def test_should_collect():
    assert True

当运行 pytest时,这只运行未标记的方法:

$ pytest test.py -v
====================================== test session starts ======================================
platform darwin -- Python 3.9.1, pytest-7.0.1, pluggy-1.0.0 -- /Users/lucaswiman/.pyenv/versions/3.9.1/bin/python3.9
cachedir: .pytest_cache
rootdir: /private/tmp
plugins: anyio-2.2.0
collected 2 items                                                                               

test.py::TestMyTest::test_should_collect PASSED                                           [ 50%]
test.py::test_should_collect PASSED                                                       [100%]

======================================= 2 passed in 0.04s =======================================

此行为已记录 here

Since Pytest 2.6, users can prevent pytest from discovering classes that start with Test by setting a boolean __test__ attribute to False.