简体   繁体   中英

running the same test against multiple implementations

If I have two implementations of a function that should do the same thing, is there any way to test both functions against the same test cases?

As I have it:

def foo1(args):
    // do some stuff
    return result1

def foo2(args):
    // do some other stuff
    return result2

import unittest

class TestFoo(unittest.TestCase):

    def test_1(self):
        arg = // something
        result = // expected result
        self.failUnless(foo1(arg) == result)

    def test_2(self):
        arg = // something
        result = // expected result
        self.failUnless(foo2(arg) == result)

But test_2 is identical to test_1, except for the function being tested. If I make a change to the test case, I must change both, and if I add more tests, I must duplicate them.

I could do something like:

class TestFoo(unittest.TestCase):
    def test_(self):
        fns = [foo1, foo2]
        arg = // something
        result = // expected result
        for fn in fns:
            self.failUnless(fn(arg) == result)

This has less code duplication, but now if either implementation fails the test, unittest doesn't report which one.

Is it possible to parameterise a TestCase by the function to be tested?

I understand that I shouldn't try to be too clever with testing, so maybe I should leave it as it is, duplicated code and all.

Here's one way usnig class attribute and inheritance.

def foo1(a, b):
    return b + a

def foo2(a, b):
    return a + b

import unittest

class TestFooBase:
    def test_1(self):
        self.assertEqual(self.impl(0, 0), 0)
    def test_2(self):
        self.assertEqual(self.impl(1, 2), 3)

class TestFoo1(unittest.TestCase, TestFooBase):
    impl = staticmethod(foo1)

    # OR
    # def impl(self, *args, **kwargs):
    #    return foo1(*args,**kwargs)


class TestFoo2(unittest.TestCase, TestFooBase):
    impl = staticmethod(foo2)

NOTE TestFooBase should not be a subclass of unittest.TestCase . Otherwise 6(3x2) tests will be run instead of 4 (2x2).

TestFooBase is not strictly necessary if you make TestFoo1 inherit from TestFoo2 (or vice versa).

class TestFoo1(unittest.TestCase):
    impl = staticmethod(foo1)
    def test_1(self):
        self.assertEqual(self.impl(0, 0), 0)
    def test_2(self):
        self.assertEqual(self.impl(1, 2), 3)

class TestFoo2(TestFoo1):
    impl = staticmethod(foo2)

BTW, failUnless is deprecated. Use assertTrue or assertEqual as shown in the above codes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM