Adam
Adam

Reputation: 657

Is it possible to use setup_method with fixtures?

I have the following code:

import pytest

@pytest.fixture
def example_smtp():
    return "example"

class TestClass(object):
    def test_function(self, example_smtp):
        # 1
        obj = NewObject(example_smtp)
        obj.initialize()

        print example_smtp
        # here may rise exception
        some_action()

        # 2
        # but we have to cleanup
        obj.cleanup()

some_action() may raise a exception, so I want to move 1 and 2 to setup_method and teardown_method, but I don't know how to do it. setup_method allows only two arguments, so I can't use example_smtp in it.

Upvotes: 0

Views: 600

Answers (2)

Bruno Oliveira
Bruno Oliveira

Reputation: 15255

A better approach is to just write a fixture that creates NewObject for you and cleans up afterwards:

import pytest

@pytest.fixture
def example_smtp():
    return "example"

class TestClass(object):

    @pytest.yield_fixture(autouse=True)
    def obj(self):
        obj = NewObject(example_smtp)
        obj.initialize()
        yield obj
        obj.cleanup()            

    def test_function(self, obj, example_smtp):
        # use obj here
        some_action(obj)

But if you really prefer to have a "setup_method"-like function (perhaps you are initializing several objects which don't appear in your snippet), you can declare an autouse fixture instead:

import pytest

@pytest.fixture
def example_smtp():
    return "example"

class TestClass(object):

    @pytest.yield_fixture(autouse=True)
    def some_setup(self):
        self.obj = ...
        # ... setup other objects, perhaps
        yield 
        # ... cleanup everything
        self.obj.cleanup()

    def test_function(self, example_smtp):
        some_action(self.obj) 

IMO, there's no compelling reason not to use fixtures when using pytest style test classes (IOW, not subclassing unittest.TestCase) because if you want a single method that does all the setup/cleanup for you you can use an autouse fixture.

Upvotes: 2

Adam
Adam

Reputation: 657

I have solved that problem with addfinalizer() function from request object.

import pytest

@pytest.fixture
def example_smtp():
        return "example"

class TestClass(object):
        @pytest.fixture
        def obj(self, request, example_smtp):
                print 'initialize', example_smtp

                def fin():
                        print 'finalize'
                request.addfinalizer(fin)

        def test(self, obj):
                some_action_raise_error()

Thank you jonrsharpe for information about yield fixtures.

Upvotes: 0

Related Questions