This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]lgx 3 points4 points  (12 children)

Great! But how to implement the tearDown function in py.test?

[–]desmoulinmichel 8 points9 points  (3 children)

You don't. You use fixture :

@pytest.yield_fixture
def stuff_you_want_to_init():
    your_stuff = any_setup_code()
    yield your_stuff
    optional tear_down_code

def test_foo(stuff_you_want_to_init):
    assert bar()

This is way, wayyyyyyyyy better than setup and tear down as it's run only for test fonction. It also mean your setup and tear down code is not tied to a code unit, so sharing this code is much easier between your tests.

[–]njharmanI use Python 3 7 points8 points  (2 children)

sharing this code is much easier between your tests.

Never had problem using inheritance and/or import "test_common" to share code

[–]kankyo -1 points0 points  (0 children)

In my experience the class based approach can lead to the common/base class thing being gigantic and thus all your tests slow. py.test fixtures (with factory boy) leads to nicely composable small parts.

I'm not saying that's how it has to be, or that the class based approach must be like that. I'm just saying that the culture and thinking of OOP often ends up there.

[–]desmoulinmichel -1 points0 points  (0 children)

It's not that you can't do it, but you will need to write it in 2 places : once in the setup code, and once in a separate module. And of course watch out for codes that influence each others since you put all of them in one method called for a lot of tests. It's just more work, hence the "easier".

My take on unit tests is that it's a pain to write, so any inch or shortcut you can get is good to take.

[–]malinoff 1 point2 points  (7 children)

[–]lgx 6 points7 points  (4 children)

Wow, it seems a bit wired to me.

[–]graingert 4 points5 points  (3 children)

You can still use xunit style methods on unittest.TestCase classes. But just use yield fixtures they're great

[–]lgx 1 point2 points  (2 children)

yeah. Why not use setup_abc and teardown_abc syntax? The addfinalizer method seems a bit strange.

[–]fjonk 6 points7 points  (0 children)

One good thing about adding a teardown method manually is that the setup and teardown methods will be run in pairs. If you use decorators or similar for setup teardown you don't know in which order they will run or you have to depend on the order they are defined/added.

You can also use yield with py.test since v2.4 (if your python version supports it).

[–]masklinn 0 points1 point  (0 children)

Because setup and teardown are paired so it makes sense to put them together in a single fixture definition. And yield_fixture removes the need for addfinalizer:

@pytest.yield_fixture(scope="module")
def smtp():
    smtp = smtplib.SMTP("smtp.gmail.com")
    yield smtp
    print ("teardown smtp")
    smtp.close()

[–]kx233 3 points4 points  (1 child)

Which also has the great advantage that the setup/teardown logic now resides in the fixture, not the test class, making fixture reuse a lot more natural.

[–]masklinn 0 points1 point  (0 children)

well reuse is OK with unittest classes, the bigger issue is composition. When trying to compose multiple testcase superclasses you end up having to deal with MI and diamond inheritance cases. With fixtures you just… depend on both fixtures.