[TIP] pytest: Setup/TearDown with fixtures
holger krekel
holger at merlinux.eu
Thu Sep 4 01:23:35 PDT 2014
Hi Floris, Laszlo,
On Wed, Sep 03, 2014 at 21:08 +0100, Floris Bruynooghe wrote:
> Hello Laszlo,
>
> All that follows is my personal opinion and may not be official best
> practices. Furthermore there are multiple ways to achieve this, what
> you did clearly already worked. Anyway, here goes:
>
> On 2 September 2014 14:58, Laszlo Papp <lpapp at kde.org> wrote:
> > Right, I think this could be added to the official documentation to
> > have a copy/pasteable example in there:
> >
> > class TestFoo:
> > @classmethod
> > @pytest.fixture(scope="class", autouse = True)
> > def setup(self, request):
> > self.session = foo.session()
> > def tearDown():
> > session.logout()
> > request.addfinalizer(tearDown)
> >
> > I am yet to test this in practice, but this simple snippet would have
> > been a timer-saver for me when writing this basic functionality ...
>
> There are 2 main issues I have with this example:
>
> 1) I actively avoid using fixture names which conflict with the xUnix
> or nose setup/teardown compatibility names to avoid confusion.
>
> 2) When using fixtures I treat the class purely as a container
> providing structure, kind of like a module. So storing state on the
> class/instance is right out. The power of fixtures comes explicitly
> from decoupling test class instances from fixture issues
> (setup/teardown) which makes fixtures much more composable due to
> better separation of concerns. This is IMHO where the power of
> fixtures comes from.
>
> With that said I would write your example as:
>
> class TestFoo:
>
> @pytest.fixture(scope='class', autouse=True)
> def session(self, request):
> session = foo.session()
> request.addfinalizer(session.logout)
I guess you want to "return session" here in order for test_bar to receive it.
> def test_foo(self):
> # test code not using the session explicitly,
> # will still be created and logged out however.
>
> def test_bar(self, session):
> # test code using session explicitly.
>
> Structuring the tests like this makes it explicit what your tests are
> doing. It may even transpire that all tests use the session in which
> case it this could be refactored to not be an autouse fixture.
I also appreciate that listing dependencies of a test function right
in the argument list makes it easy to understand what a test depends on.
By contrast, if you use autouse or xUnit style setupX methods a reader
of your test function needs to deduce that they are called.
best,
holger
> As a bonus this also avoids the confusion of class methods and their
> first argument (self? cls? Am I now assigning to the class or
> instance?).
>
>
> As for having a clearer example in the documentation as this being the
> equivalent in the documentation: it would be great if you could create
> a PR with this your original xUnit example and the fixture-based
> equivalent. Then people after you will hopefully find the mental step
> to convert tests from this pattern more easily.
>
>
> Best regards,
> Floris
>
>
> --
> Debian GNU/Linux -- The Power of Freedom
> www.debian.org | www.gnu.org | www.kernel.org
>
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python
>
More information about the testing-in-python
mailing list