Dynamic discovery?

1 view
Skip to first unread message

Skip Montanaro

unread,
Sep 14, 2008, 10:01:00 AM9/14/08
to nose-users
I have three variants of a class I'd like to test. All adhere to
the same API. (This is the lockfile module, FYI, available from
PyPI.) Conceptually, I'd like to have the tests executed something
like this:

FileLock = LinkFileLock # the default

def test_1():
...

def test_2():
...

for FileLock in (LinkFileLock, MkdirFileLock, SQLiteFileLock):
test_1()
test_2()

and have nosetests report each execution of test_1 and test_2.
That is, I'd like it to report execution of six test cases instead
of the two it would report with the above code.

I realize I can do something like this:

def test_1_LinkFileLock():
global FileLock
FileLock, Lock = LinkFileLock, FileLock
test_1()
FileLock = Lock

but with more than a couple core tests I wind up with a lot of
duplicated test harness code. Is there some way for
nose to recognize the multiple executions of test_1 as
independent test cases?

Thx,

Skip Montanaro

Pete

unread,
Sep 14, 2008, 11:28:14 AM9/14/08
to nose-...@googlegroups.com
I'm doing much the same thing - I have a common abstract base class
that defines an interface and about half a dozen implementations. I
wrote what I've heard called compliance tests.

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

skip.mo...@gmail.com

unread,
Sep 14, 2008, 2:38:40 PM9/14/08
to nose-...@googlegroups.com

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

Kumar McMillan

unread,
Sep 14, 2008, 2:51:01 PM9/14/08
to nose-...@googlegroups.com
as an alternative to Pete's suggestion you can use nose's test
generators like this:

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

Reply all
Reply to author
Forward
0 new messages