[pytest-dev] Unexpected fixture behaviour.

holger krekel holger at merlinux.eu
Mon Apr 7 13:00:08 CEST 2014


Hi again,

On Mon, Apr 07, 2014 at 13:55 +0300, Anton P wrote:
> Hi Holger,
> 
> Thank you for your response!
> 
> No, we haven't switched py.test versions. We just move all setup/teardown
> procedures from pytest hooks to fixtures.
> 
> I'll update issue #498.

great, thanks.  I think that in case of a failing finalizer a fixture 
might be marked as "broken" or so, and no attempt at re-creating it
be made.  Subsequent tests would not run (not sure how that gets reported
exactly, though).  Reporting a teardown error and then trying to
recreate it might work in some cases but might also lead to even
stranger errors because the fixture might still be half-setup
due to the failed finalizer.

best,
holger


> Thank you!
> Anton
> 
> 
> On Mon, Apr 7, 2014 at 1:51 PM, holger krekel <holger at merlinux.eu> wrote:
> 
> > Hi Anton,
> >
> > just to understand better -- you also switched pytest versions or not?
> > A mere change from "pytest_funcarg__" syntax to "@pytest.fixture"
> > syntax should not have such an effect.
> >
> > There also is issue498 which might be related, btw:
> >
> > https://bitbucket.org/hpk42/pytest/issue/498/function-scope-fixture-with-failing
> >
> > Could you file an issue against the tracker and/or add to 498?
> >
> > best and thanks,
> >
> > holger
> >
> > On Mon, Apr 07, 2014 at 13:43 +0300, Anton P wrote:
> > > Hi All,
> > >
> > > Recently we switched our test environment from funcargs to fixtures and
> > > found unexpected and unwanted behaviour: In case fixture finalizer failed
> > > next time fixture won't be set up.
> > >
> > > Here I have 2 fixtures:
> > > env_main - module level
> > > env - functional level (env_main child)
> > >
> > > In pytest output you can see message that env was created before test_1
> > > ("INIT_ENV" message). Then it failed on finalizer after "DESTROY ENV"
> > > message.
> > > PROBLEM: test_2 that requires env fixture is launched but without env
> > > fixture.
> > > I expect that function level fixture will be recreated for the next test
> > > function, or at least all other test functions will fail without
> > launching.
> > > I don't see any reason why they have to be launched in case fixture
> > cannot
> > > be set up. But it's better to try to recreate fixture for next iteration
> > > (e.g. next function if scope is function)
> > >
> > > I see there was an issue #287 which is marked as resolved. But as for me
> > it
> > > could be reopened.
> > >
> > > I see that in case we add more test cases, then the fixture will be
> > created
> > > for the 3d test function but again skipped for the 4th test function.
> > >
> > > Is it possible to change current default behaviour?
> > >
> > > Thank you in advance!
> > > Anton
> > >
> > > P.S.
> > > Please find code files attached.
> > >
> > > Here is execution log:
> > >
> > > $ py.test -v -s test_params.py
> > > ============================ test session starts
> > > ============================
> > > platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2 --
> > > /usr/bin/python
> > > plugins: cov
> > > collected 2 items
> > >
> > > test_params.py:4: TestClass.test_1 Create ENV_MAIN
> > > INIT ENV
> > > PASSEDDESTROY ENV
> > >
> > > test_params.py:4: TestClass.test_1 ERROR
> > > test_params.py:7: TestClass.test_2 PASSEDDestroy ENV_MAIN
> > >
> > >
> > > ================================== ERRORS
> > > ===================================
> > > ___________________ ERROR at teardown of TestClass.test_1
> > > ___________________
> > >
> > > self = <conftest.EnvTest instance at 0x2025878>
> > >
> > >     def teardown(self):
> > >         print "DESTROY ENV"
> > > >       assert 0
> > > E       assert 0
> > >
> > > conftest.py:30: AssertionError
> > > ===================== 2 passed, 1 error in 0.01 seconds
> > > =====================
> >
> > > import pytest
> > > import sys
> > >
> > > class Env():
> > >     def __init__(self):
> > >         self.env = 1
> > >
> > >     def create(self):
> > >         print "Create ENV_MAIN"
> > >
> > >         return self.env
> > >
> > >     def destroy(self):
> > >         print "Destroy ENV_MAIN"
> > >
> > >
> > > class EnvTest():
> > >
> > >     def __init__(self, request, env):
> > >         self.request = request
> > >         self.env = env
> > >         self.request.node.call_status = False
> > >
> > >     def setup(self):
> > >         print "INIT ENV"
> > >         self.request.node.call_status = True
> > >
> > >     def teardown(self):
> > >         print "DESTROY ENV"
> > >         assert 0
> > >
> > >
> > >
> > > @pytest.fixture(scope="module")
> > > def env_main(request):
> > >     env_wrapper = Env()
> > >
> > >     request.addfinalizer(env_wrapper.destroy)
> > >     request.config.env = env_wrapper.create()
> > >
> > >     return env_wrapper
> > >
> > > @pytest.fixture
> > > def env(request, env_main):
> > >     env = EnvTest(request, env_main)
> > >     request.addfinalizer(env.teardown)
> > >     env.setup()
> > >
> > >     return env_main
> >
> > > import pytest
> > >
> > > class TestClass():
> > >     def test_1(self, env):
> > >         pass
> > >
> > >     def test_2(self, env):
> > >         pass
> >
> > > _______________________________________________
> > > Pytest-dev mailing list
> > > Pytest-dev at python.org
> > > https://mail.python.org/mailman/listinfo/pytest-dev
> >
> >


More information about the Pytest-dev mailing list