Monday, June 2, 2008

Test inelegance

There's some NumPy tests that use a class derived from unittest.TestCase to contain a set of tests that need to be run on multiple types, and then inherit from that class to implement the generic test, like this:

class LinalgTestCase(NumpyTestCase):
def test_single(self):
a = array([[1.,2.], [3.,4.]], dtype=single)
b = array([2., 1.], dtype=single)
self.do(a, b)

def test_double(self):
a = array([[1.,2.], [3.,4.]], dtype=double)
b = array([2., 1.], dtype=double)
self.do(a, b)


class test_inv(LinalgTestCase):
def do(self, a, b):
a_inv = linalg.inv(a)
assert_almost_equal(dot(a, a_inv), identity(a.shape[0]))


It seems that nose wants to run the LinalgTestCase class directly, since it's derived from TestCase, which of course raises silly errors. So for the time being I'm using the __test__ attribute to force nose to run the correct class:

class LinalgTestCase(NumpyTestCase):
__test__ = False
def test_single(self):
a = array([[1.,2.], [3.,4.]], dtype=single)
b = array([2., 1.], dtype=single)
self.do(a, b)

def test_double(self):
a = array([[1.,2.], [3.,4.]], dtype=double)
b = array([2., 1.], dtype=double)
self.do(a, b)


class test_inv(LinalgTestCase):
__test__ = True
def do(self, a, b):
a_inv = linalg.inv(a)
assert_almost_equal(dot(a, a_inv), identity(a.shape[0]))

This seems like an ugly way to make the tests run properly, but it works for the moment. If I can find a prettier method later I'll switch to it.