views:

94

answers:

2

I have problem organizing my unittest based class test for family of tests. For example assume I implement a "dictionary" interface, and have 5 different implementations want to testing.

I do write one test class that tests a dictionary interface. But how can I nicely reuse it to test my all classes? So far I do ugly:

DictType = hashtable.HashDict

In top of file and then use DictType in test class. To test another class I manually change the DictType to something else.

How can do this otherwise? Can't pass arguments to unittest classes so is there a nicer way?

A: 

You could look at testscenarios which allows you to set a list called scenarios. The code then generates a version of the test class for each value/scenario in the list

See the example

So in your case the scenarios would be a list like [ {dicttype:hashtable.HashDict}, {dicttype:otherimpl.class}, ] and use self.dicttype in your test code.

Mark
oh, so this can't possible with just standard unittest? very dissapointing :-(
zaharpopov
Not yet - see http://www.voidspace.org.uk/python/articles/unittest2.shtml for what is being done
Mark
+1  A: 

The way I tackle this with standard unittest is by subclassing -- overriding data is as easy as overriding methods, after all.

So, I have a base class for the tests:

class MappingTestBase(unittest.TestCase):
    dictype = None
    # write all the tests using self.dictype

and subclasses:

class HashtableTest(MappingTestBase):
    dictype = hashtable.HashDict

class OtherMappingTest(MappingTestBase):
    dictype = othermodule.mappingimpl

Here, the subclasses need override only dictype. Sometimes it's handier to also expose MappingTestBase use "hook methods". When the types being tested don't have exactly identical interfaces in all cases, this can be worked around by having the subclasses override the hook methods as needed -- this is the "Template Method" design pattern, see e.g. this page which has a commented and timelined collection of a couple of video lectures of mine on design patterns -- part II is about Template Method and variants thereof for about the first 30 minutes.

You don't have to have all of this in a single module, of course (though I often find it clearest to lay things out this way, you could also make one separate test module per type you're testing, each importing the module with the abstract base class).

Alex Martelli
oh, very nice, 10x alex
zaharpopov