replacing __dict__ with an OrderedDict

Ulrich Eckhardt ulrich.eckhardt at dominolaser.com
Mon Jan 9 11:59:45 EST 2012


Am 09.01.2012 15:35, schrieb Roy Smith:
> The classic unittest philosophy says that tests should be independent of
> each other, which means they should be able to be run in arbitrary
> order.  Some people advocate that the test framework should
> intentionally randomize the order, to flush out inter-test dependencies
> that the author didn't realize existed (or intend).

While I agree with the idea, I'd like to add that independence is an 
illusion. You already have possible dependencies if you run tests in the 
same process/OS-installation/computer/parallel universe. If you now 
happen to influence one test with another and the next run randomizes 
the tests differently, you will never see the fault again. Without this 
reproducability, you don't gain anything but the bad stomach feeling 
that something is wrong.


> Test independence is a good thing.  Many people don't understand this
> when writing tests, and inadvertently write tests that depend on each
> other.  I've worked with those systems.  They're a bear to debug.
> You've got some test suite that runs for 15 minutes and dies at case 37
> of 43.  If you try to run case 37 by itself, it won't run, and you can't
> figure out what state cases 1-36 were supposed to leave the system in to
> make 37 work.  You could sink days or weeks into debugging this kind of
> crap.  BTDT.

I'm sorry to hear that, debugging other peoples' feces is never a task 
to wish for. That said, there are two kinds of dependencies and in at 
least this discussion there hasn't been any mentioning of the 
differences yet, but those differences are important.


Your unfortunate case is where test X creates persistent state that must 
be present in order for test X+1 to produce meaningful results. This 
kind of dependency obviously blows, as it means you can't debug test X+1 
separately. I'd call this operational dependency.

This kind of dependency is IMHO a bug in the tests themselves. The unit 
testing framework could help you find those bugs by allowing random 
order of execution for the test cases.


There is another dependency and that I'd call a logical dependency. This 
occurs when e.g. test X tests for an API presence and test Y tests the 
API behaviour. In other words, Y has no chance to succeed if X already 
failed. Unfortunately, there is no way to express this relation, there 
is no "@unittest.depends(test_X)" to decorate test_Y with (Not yet!). 
Each test would be the root of a tree of tests that it depends on. If a 
dependency fails already, you can either skip the tree or at least mark 
the following test failures as implicit failures, so that you can easily 
distinguish them from the root cause.

This kind of dependency is quite normal although not directly supported 
by the unittest module. As a workaround, being able to define an order 
allows you to move the dependencies further to the top, so they are 
tested first.


To sum it up, in order to catch operational dependencies, you need a 
random order while in order to clearly express logical dependencies in 
the output, you want a fixed order. Neither is the one true way, though 
my gut feeling is that the fixed order is overall more useful.


> As long as they understand the consequences of their actions, don't
> try to preach unittest religion to them.  They're in the best
> position to know if what they're trying to do is the best thing for
> their particular situation.

Amen!

Uli



More information about the Python-list mailing list