remove support for @pytest.fixture on classes, to be reserved for future use:
Fixture-classes could offer setup/teardown/addoption/configure methods and provide higher level support. Preliminary allowing it to work on classes may make introducing it harder.
This commit is contained in:
parent
d630d02c5b
commit
df643f65f0
|
@ -17,6 +17,8 @@ class FixtureFunctionMarker:
|
|||
self.autoactive = autoactive
|
||||
|
||||
def __call__(self, function):
|
||||
if inspect.isclass(function):
|
||||
raise ValueError("class fixtures not supported (may be in the future)")
|
||||
function._pytestfixturefunction = self
|
||||
return function
|
||||
|
||||
|
@ -43,7 +45,7 @@ def fixture(scope="function", params=None, autoactive=False):
|
|||
can see it. If False (the default) then an explicit
|
||||
reference is needed to activate the fixture.
|
||||
"""
|
||||
if hasattr(scope, "__call__") and params is None and autoactive == False:
|
||||
if py.builtin.callable(scope) and params is None and autoactive == False:
|
||||
# direct decoration
|
||||
return FixtureFunctionMarker("function", params, autoactive)(scope)
|
||||
else:
|
||||
|
@ -1563,10 +1565,8 @@ class FixtureDef:
|
|||
|
||||
def getfuncargnames(function, startindex=None):
|
||||
# XXX merge with main.py's varnames
|
||||
if inspect.isclass(function):
|
||||
function = function.__init__
|
||||
startindex = 1
|
||||
elif startindex is None:
|
||||
#assert not inspect.isclass(function)
|
||||
if startindex is None:
|
||||
startindex = inspect.ismethod(function) and 1 or 0
|
||||
argnames = inspect.getargs(py.code.getrawcode(function))[0]
|
||||
defaults = getattr(function, 'func_defaults',
|
||||
|
|
|
@ -569,8 +569,7 @@ self-contained implementation of this idea::
|
|||
|
||||
import pytest
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
class db:
|
||||
class DB:
|
||||
def __init__(self):
|
||||
self.intransaction = []
|
||||
def begin(self, name):
|
||||
|
@ -578,6 +577,10 @@ self-contained implementation of this idea::
|
|||
def rollback(self):
|
||||
self.intransaction.pop()
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def db():
|
||||
return DB()
|
||||
|
||||
class TestClass:
|
||||
@pytest.fixture(autoactive=True)
|
||||
def transact(self, request, db):
|
||||
|
@ -590,9 +593,9 @@ self-contained implementation of this idea::
|
|||
def test_method2(self, db):
|
||||
assert db.intransaction == ["test_method2"]
|
||||
|
||||
The class-level ``transact`` fixture is marked with *autoactive=true* which implies
|
||||
that all test methods in the class will use this fixture without a need to
|
||||
specify it.
|
||||
The class-level ``transact`` fixture is marked with *autoactive=true*
|
||||
which implies that all test methods in the class will use this fixture
|
||||
without a need to specify it.
|
||||
|
||||
If we run it, we get two passing tests::
|
||||
|
||||
|
@ -614,11 +617,10 @@ And here is how autoactive fixtures work in other scopes:
|
|||
a global fixture should always quickly determine if it should do
|
||||
any work and avoid expensive imports or computation otherwise.
|
||||
|
||||
Note that the above ``transact`` fixture may very well be something that
|
||||
you want to make available in your project but which requires an explicit using
|
||||
reference to have it activated. The canonical way to do that is to put
|
||||
the transact definition into a conftest.py file without using
|
||||
``autoactive``::
|
||||
Note that the above ``transact`` fixture may very well be a fixture that
|
||||
you want to make available in your project without having it generally
|
||||
active. The canonical way to do that is to put the transact definition
|
||||
into a conftest.py file without using ``autoactive``::
|
||||
|
||||
# content of conftest.py
|
||||
@pytest.fixture()
|
||||
|
@ -626,15 +628,16 @@ the transact definition into a conftest.py file without using
|
|||
db.begin()
|
||||
request.addfinalizer(db.rollback)
|
||||
|
||||
and then have a TestClass using it by declaring the need::
|
||||
and then e.g. have a TestClass using it by declaring the need::
|
||||
|
||||
@pytest.mark.usefixtures("transact")
|
||||
class TestClass:
|
||||
def test_method1(self):
|
||||
...
|
||||
|
||||
While all test methods in this TestClass will use the transaction
|
||||
fixture, other test classes or function will not do so without a marker or funcarg.
|
||||
All test methods in this TestClass will use the transaction fixture while
|
||||
other test classes or functions will not do so unless they also add
|
||||
a ``transact`` reference.
|
||||
|
||||
controlled visibility of fixture functions
|
||||
----------------------------------------------------
|
||||
|
|
|
@ -547,10 +547,6 @@ def test_getfuncargnames():
|
|||
if sys.version_info < (3,0):
|
||||
assert funcargs.getfuncargnames(A.f) == ['arg1']
|
||||
|
||||
class A:
|
||||
def __init__(self, x):
|
||||
pass
|
||||
assert funcargs.getfuncargnames(A) == ["x"]
|
||||
|
||||
class TestFillFixtures:
|
||||
def test_fillfuncargs_exposed(self):
|
||||
|
@ -1803,7 +1799,7 @@ class TestFixtureUsages:
|
|||
*fixture*'missing'*not found*
|
||||
""")
|
||||
|
||||
def test_factory_setup_as_classes(self, testdir):
|
||||
def test_factory_setup_as_classes_fails(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
class arg1:
|
||||
|
@ -1811,17 +1807,10 @@ class TestFixtureUsages:
|
|||
self.x = 1
|
||||
arg1 = pytest.fixture()(arg1)
|
||||
|
||||
class MySetup:
|
||||
def __init__(self, request, arg1):
|
||||
request.instance.arg1 = arg1
|
||||
pytest.fixture(autoactive=True)(MySetup)
|
||||
|
||||
class TestClass:
|
||||
def test_method(self):
|
||||
assert self.arg1.x == 1
|
||||
""")
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
l = reprec.getfailedcollections()
|
||||
assert len(l) == 1
|
||||
|
||||
def test_request_can_be_overridden(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
|
|
Loading…
Reference in New Issue