I’ve been looking at unittest fixtures, and seeing how they are treated in unittest, nose, and pytest.

I started out with the assumption that unittest was correct.

Now. I don’t think it is.



Update: Hmmm… changed my stance on this. … there are better ways to ensure teardown happens. But it was an interesting discussion…

From the unittest documentation

For tearDown(): “This method will only be called if the setUp() succeeds, regardless of the outcome of the test method.”

For tearDownClass(): “If an exception is raised during a setUpClass then the tests in the class are not run and the tearDownClass is not run.“

For tearDownModule(): “If an exception is raised in a setUpModule then none of the tests in the module will be run and the tearDownModule will not be run.“

OK. Clear enough. But is that really the right behavior?

The reasoning behind it, in my opinion

If we are only doing one thing in setUp(), and that thing fails, then there is nothing to clean up.

Good so far.

Where it falls apart

But what if we are doing more than one thing in setUp?

What if, in setUp, we:

create a temporary directory, and create some files there to work on open a connection to a remote database some other stuff

Then, in tearDown, we:

clean up the “other stuff” close the connection to the database remove the temporary directory and all of its contents

What if our connection to the database fails, and throws an exception?

In the unittest and nose implementation, the temporary directory and the “other stuff” will not be cleaned up.

I just think that’s wrong.

If you want to protect for that, currently, then you need to use addCleanup() to attach clean up functions to the tests.

These will be called, even if setUp() raises an exception.

That only works for setUp()/test()/tearDown()/cleanup().

It DOESN’T work for setUpClass().

It DOESN’T work for setUpModule().

Proposed change: ALWAYS call tearDown() regardless of the success of setUp()

This goes for tearDown(),tearDownClass(), and tearDownModule() as well.

Is it too late?

I don’t think so.

It it is too late for unittest, and nose, it’s NOT too late for pytest.

Perhaps we can just fix it there.

Feedback, please

I really want to know what others think of this.

Or does anyone even care about this corner case of unittest fixture behavior?

Cheers.