support nose-style ``__test__`` attribute on modules, classes and
functions, including unittest-style Classes. If set to True, the test will not be collected. --HG-- branch : nose_test_attr
This commit is contained in:
parent
f91049cec9
commit
494be731e3
|
@ -64,6 +64,10 @@ NEXT (2.6)
|
||||||
- fix issue443: fix skip examples to use proper comparison. Thanks Alex
|
- fix issue443: fix skip examples to use proper comparison. Thanks Alex
|
||||||
Groenholm.
|
Groenholm.
|
||||||
|
|
||||||
|
- support nose-style ``__test__`` attribute on modules, classes and
|
||||||
|
functions, including unittest-style Classes. If set to True, the
|
||||||
|
test will not be collected.
|
||||||
|
|
||||||
|
|
||||||
2.5.2
|
2.5.2
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
|
@ -314,6 +314,9 @@ class PyCollector(PyobjMixin, pytest.Collector):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
|
if not getattr(self.obj, "__test__", True):
|
||||||
|
return []
|
||||||
|
|
||||||
# NB. we avoid random getattrs and peek in the __dict__ instead
|
# NB. we avoid random getattrs and peek in the __dict__ instead
|
||||||
# (XXX originally introduced from a PyPy need, still true?)
|
# (XXX originally introduced from a PyPy need, still true?)
|
||||||
dicts = [getattr(self.obj, '__dict__', {})]
|
dicts = [getattr(self.obj, '__dict__', {})]
|
||||||
|
|
|
@ -41,10 +41,12 @@ class UnitTestCase(pytest.Class):
|
||||||
super(UnitTestCase, self).setup()
|
super(UnitTestCase, self).setup()
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
|
cls = self.obj
|
||||||
|
if not getattr(cls, "__test__", True):
|
||||||
|
return
|
||||||
self.session._fixturemanager.parsefactories(self, unittest=True)
|
self.session._fixturemanager.parsefactories(self, unittest=True)
|
||||||
loader = py.std.unittest.TestLoader()
|
loader = py.std.unittest.TestLoader()
|
||||||
module = self.getparent(pytest.Module).obj
|
module = self.getparent(pytest.Module).obj
|
||||||
cls = self.obj
|
|
||||||
foundsomething = False
|
foundsomething = False
|
||||||
for name in loader.getTestCaseNames(self.obj):
|
for name in loader.getTestCaseNames(self.obj):
|
||||||
x = getattr(self.obj, name)
|
x = getattr(self.obj, name)
|
||||||
|
|
|
@ -25,6 +25,7 @@ Supported nose Idioms
|
||||||
* SkipTest exceptions and markers
|
* SkipTest exceptions and markers
|
||||||
* setup/teardown decorators
|
* setup/teardown decorators
|
||||||
* yield-based tests and their setup
|
* yield-based tests and their setup
|
||||||
|
* ``__test__`` attribute on modules/classes/functions
|
||||||
* general usage of nose utilities
|
* general usage of nose utilities
|
||||||
|
|
||||||
Unsupported idioms / known issues
|
Unsupported idioms / known issues
|
||||||
|
|
|
@ -164,20 +164,21 @@ class TestMockDecoration:
|
||||||
names = [x.nodeid.split("::")[-1] for x in calls]
|
names = [x.nodeid.split("::")[-1] for x in calls]
|
||||||
assert names == ["test_one", "test_two", "test_three"]
|
assert names == ["test_one", "test_two", "test_three"]
|
||||||
|
|
||||||
def test_mock_double_patch_issue473(self, testdir):
|
def test_mock_and_mark_issue473(self, testdir):
|
||||||
|
pytest.importorskip("mock", "1.0.1")
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
from mock import patch
|
from mock import patch
|
||||||
from pytest import mark
|
from pytest import mark
|
||||||
|
|
||||||
@patch('os.getcwd')
|
@patch('os.getcwd')
|
||||||
@patch('os.path')
|
@patch('os.path')
|
||||||
@mark.slow
|
#@mark.slow
|
||||||
class TestSimple:
|
class TestSimple:
|
||||||
def test_simple_thing(self, mock_path, mock_getcwd):
|
def test_simple_thing(self, mock_path, mock_getcwd):
|
||||||
pass
|
pass
|
||||||
""")
|
""")
|
||||||
res = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
res.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
|
||||||
class TestReRunTests:
|
class TestReRunTests:
|
||||||
|
@ -214,3 +215,49 @@ class TestReRunTests:
|
||||||
def test_pytestconfig_is_session_scoped():
|
def test_pytestconfig_is_session_scoped():
|
||||||
from _pytest.python import pytestconfig
|
from _pytest.python import pytestconfig
|
||||||
assert pytestconfig._pytestfixturefunction.scope == "session"
|
assert pytestconfig._pytestfixturefunction.scope == "session"
|
||||||
|
|
||||||
|
|
||||||
|
class TestNoselikeTestAttribute:
|
||||||
|
def test_module(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
__test__ = False
|
||||||
|
def test_hello():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
calls = reprec.getreports("pytest_runtest_logreport")
|
||||||
|
assert not calls
|
||||||
|
|
||||||
|
def test_class_and_method(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
__test__ = True
|
||||||
|
def test_func():
|
||||||
|
pass
|
||||||
|
test_hello.__test__ = False
|
||||||
|
|
||||||
|
class TestSome:
|
||||||
|
__test__ = False
|
||||||
|
def test_method(self):
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
calls = reprec.getreports("pytest_runtest_logreport")
|
||||||
|
assert not calls
|
||||||
|
|
||||||
|
def test_unittest_class(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import unittest
|
||||||
|
class TC(unittest.TestCase):
|
||||||
|
def test_1(self):
|
||||||
|
pass
|
||||||
|
class TC2(unittest.TestCase):
|
||||||
|
__test__ = False
|
||||||
|
def test_2(self):
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
call = reprec.getcalls("pytest_collection_modifyitems")[0]
|
||||||
|
assert len(call.items) == 1
|
||||||
|
assert call.items[0].cls.__name__ == "TC"
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue