1

I'm researching new version of pytest (2.3) and getting very excited about the new functionality where you

"can precisely control teardown by registering one or multiple teardown functions as soon as they have performed some actions which need undoing, eliminating the no need for a separate “teardown” decorator"

from here

It's all pretty clear when it's used as function, but how to use it in the class?

class Test(object):

    @pytest.setup(scope='class')
    def stp(self):
        self.propty = "something"

    def test_something(self):
    ... # some code
    # need to add something to the teardown

    def test_something_else(self):
    ... # some code
    # need to add even more to the teardown
László Papp
  • 51,870
  • 39
  • 111
  • 135
Alex Okrushko
  • 7,212
  • 6
  • 44
  • 63

2 Answers2

3

Ok, I got it working by having a 'session'-wide funcarg finalizer:

@pytest.fixture(scope = "session")
def finalizer():
    return Finalizer()

class Finalizer(object):

    def __init__(self):
        self.fin_funcs = []

    def add_fin_func(self, func):
        self.fin_funcs.append(func)

    def remove_fin_func(self, func):
        try:
            self.fin_funcs.remove(func)
        except:
            pass

    def execute(self):
        for func in reversed(self.fin_funcs): 
            func()
        self.fin_funcs = []     

class TestSomething(object):

    @classmethod
    @pytest.fixture(scope = "class", autouse = True)
    def setup(self, request, finalizer):

        self.finalizer = finalizer
        request.addfinalizer(self.finalizer.execute)
        self.finalizer.add_fin_func(lambda: some_teardown())

    def test_with_teardown(self):

        #some test
        self.finalizer.add_fin_func(self.additional_teardown)

    def additional_teardown(self):
        #additional teardown

Thanks @hpk42 for answering e-mails and helping me get the final version.

NOTE: together with xfailing the rest of the steps and improved scenarios this now makes a pretty good Test-Step structure

Community
  • 1
  • 1
Alex Okrushko
  • 7,212
  • 6
  • 44
  • 63
0

Indeed, there are no good examples for teardown yet. The request object has a addfinalizer method. Here is an example usage:

@pytest.setup(scope=...)
def mysetup(request):
     ...
     request.addfinalizer(finalizerfunction)
     ...

The finalizerfunction will be called when all tests withing the scope finished execution.

hpk42
  • 21,501
  • 4
  • 47
  • 53
  • Yes, I've seen that `request.addfinalizer()`, but how to access `request` object in the class under test? btw, I like this `addfinalizer` idea, it has great potential. – Alex Okrushko Sep 22 '12 at 16:11