I'm using pytest to test some code based on TensorFlow.
A TestCase
is defined for simplicity like:
class TestCase(tf.test.TestCase):
# ...
The problem is tf.test.TestCase
provide a useful function self.test_session()
, which was treated as a test method in pytest since its name starts with test_
.
The result pytest report more succeed tests than test methods I defined due to test_session()
methods.
I use the following code to skip test_session
:
class TestCase(tf.test.TestCase):
@pytest.mark.skip
@contextmanager
def test_session(self):
with super().test_session() as sess:
yield sess
However there would be some "s" in test report indicating there are some skip tests.
Is there anyway I can mark one exact method not a test method without changing pytest test discovery rules globally?
Running pytest We can run a specific test file by giving its name as an argument. A specific function can be run by providing its name after the :: characters. Markers can be used to group tests. A marked grouped of tests is then run with pytest -m .
The simplest way to skip a test is to mark it with the skip decorator which may be passed an optional reason . It is also possible to skip imperatively during test execution or setup by calling the pytest. skip(reason) function. This is useful when it is not possible to evaluate the skip condition during import time.
To use markers, we have to import pytest module in the test file. We can define our own marker names to the tests and run the tests having those marker names. -m <markername> represents the marker name of the tests to be executed.
Usually you can use TestCase.skipTest() or one of the skipping decorators instead of raising this directly. Skipped tests will not have setUp() or tearDown() run around them. Skipped classes will not have setUpClass() or tearDownClass() run.
Filter out false positives after the test items are collected: create a conftest.py
in your tests directory with the custom post-collection hook:
# conftest.py
def pytest_collection_modifyitems(session, config, items):
items[:] = [item for item in items if item.name != 'test_session']
pytest
will still collect the test_session
methods (you will notice that in the pytest
report line collected n tests
), but not execute them as tests and not consider them anywhere in the test run.
unittest
-style testsCheck out this answer.
You can set __test__ = False
, either directly, or by writing a simple decorator. The latter should behave similarly to Nose's nottest
decorator.
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
When running pytest, this only runs the methods which are not marked:
$ 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 =======================================
This behavior is documented here:
Since Pytest 2.6, users can prevent pytest from discovering classes that start with Test by setting a boolean
__test__
attribute toFalse
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With