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:
holger krekel 2012-10-08 11:22:31 +02:00
parent d630d02c5b
commit df643f65f0
3 changed files with 24 additions and 32 deletions

View File

@ -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',

View File

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

View File

@ -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("""