I did something like:
class FileComplianceTest(object):
def setup_hook():
do_common_setup()
do_backend_specific_setup()
def do_backend_specific_setup()
raise NotImplementedError
def test_1():
do_common_test_1()
def test_2():
do_common_test_2()
class TestLinkFile(FileComplianceTest):
def do_backend_specific_setup():
...
class TestSqliteFile(FileComplianceTest):
def do_backend_specific_setup():
...
and so forth. This technique works best when your API is identical
(though you can add implementation specific tests in the subclasses)
but you have slightly different harness/setup code.
My real code lives here: http://code.google.com/p/grassyknoll/source/browse/branches/unhork/grassyknoll/tests/test_backends
It's a bit more involved (I have multiple test base classes for each
implementation & some magic in the setup_hook), but should give you an
idea of the possibilities of this technique.
--Pete
Pete> I'm doing much the same thing - I have a common abstract base
Pete> class that defines an interface and about half a dozen
Pete> implementations. I wrote what I've heard called compliance tests.
Pete> I did something like:
Pete> class FileComplianceTest(object):
...
Pete> class TestLinkFile(FileComplianceTest):
Pete> def do_backend_specific_setup():
Pete> ...
Pete> class TestSqliteFile(FileComplianceTest):
Pete> def do_backend_specific_setup():
Pete> ...
Excellent! Worked like a charm.
Thanks,
Skip
def run_common_lock_tests(FileLock):
lock = FileLock()
...
def test_all_lock_types():
for FileLock in (LinkFileLock, MkdirFileLock, SQLiteFileLock):
yield run_common_lock_tests, FileLock