unittest.TestCase and functools.partial don't seem to mix

Discussion in 'Python' started by Joel Smith, Oct 6, 2009.

  1. Joel Smith

    Joel Smith Guest

    Hi List,
    I want to make some test case classes that can have some data passed in
    to modify the way they behave. I can't see a straightforward manner to
    pass data to an __init__() method of a class derived from
    unittest.TestCase, or to pass data to a test function within that
    class. Being a C++ guy, I thought "If only Python had something
    equivalent to boost::bind, I'd be fine," and then I discovered
    functools.partial. I found a post showing how to create classes using
    partial, and I thought I was good to go. The post I found is here:

    http://mail.python.org/pipermail/bangpypers/2008-December/000974.html

    So I adapted that code to see if it worked in the context of unittest.
    When I run the code, it acts like the parameter I provided with partial
    isn't even there. Any ideas?

    #!/usr/bin/python

    import functools
    import unittest

    class GenericWindow:
    def __init__(self, name, width, height, color='white'):
    print('Name: %s, width: %d, height: %d, color: %s' % (name, width,
    height, color))

    class TestGenericWindow(unittest.TestCase):
    def __init__(self, methodName, color):
    unittest.TestCase.__init__(self, methodName)
    print('color: %s' % color)
    self.color = color

    def testit():
    GenericWindow('foo', width=100, height=100, color=self.color)

    def suite():
    s = unittest.Suite()
    BrownWindowTest = functools.partial(TestGenericWindow, color='brown')
    BlueWindowTest = functools.partial(TestGenericWindow, color='blue')
    GreenWindowTest = functools.partial(TestGenericWindow, color='green')
    s.addTest(unittest.makeSuite(BrownWindowTest))
    s.addTest(unittest.makeSuite(BlueWindowTest))
    s.addTest(unittest.makeSuite(GreenWindowTest))
    return s

    if __name__ == '__main__': #unittest.main()
    unittest.main()

    That code gives the following:

    Traceback (most recent call last):
    File "./functools.partial.py", line 32, in <module>
    unittest.main()
    File "/usr/lib/python2.6/unittest.py", line 816, in __init__
    self.parseArgs(argv)
    File "/usr/lib/python2.6/unittest.py", line 837, in parseArgs
    self.test = self.testLoader.loadTestsFromModule(self.module)
    File "/usr/lib/python2.6/unittest.py", line 559, in loadTestsFromModule
    tests.append(self.loadTestsFromTestCase(obj))
    File "/usr/lib/python2.6/unittest.py", line 550, in loadTestsFromTestCase
    return self.suiteClass(map(testCaseClass, testCaseNames))
    TypeError: __init__() takes exactly 3 arguments (2 given)

    Thanks for having a look,
    Joel
    Joel Smith, Oct 6, 2009
    #1
    1. Advertising

  2. Joel Smith

    Peter Otten Guest

    Joel Smith wrote:

    > Hi List,
    > I want to make some test case classes that can have some data passed in
    > to modify the way they behave. I can't see a straightforward manner to
    > pass data to an __init__() method of a class derived from
    > unittest.TestCase, or to pass data to a test function within that
    > class. Being a C++ guy, I thought "If only Python had something
    > equivalent to boost::bind, I'd be fine," and then I discovered
    > functools.partial. I found a post showing how to create classes using
    > partial, and I thought I was good to go. The post I found is here:
    >
    > http://mail.python.org/pipermail/bangpypers/2008-December/000974.html
    >
    > So I adapted that code to see if it worked in the context of unittest.
    > When I run the code, it acts like the parameter I provided with partial
    > isn't even there. Any ideas?
    >
    > #!/usr/bin/python
    >
    > import functools
    > import unittest
    >
    > class GenericWindow:
    > def __init__(self, name, width, height, color='white'):
    > print('Name: %s, width: %d, height: %d, color: %s' % (name, width,
    > height, color))
    >
    > class TestGenericWindow(unittest.TestCase):
    > def __init__(self, methodName, color):
    > unittest.TestCase.__init__(self, methodName)
    > print('color: %s' % color)
    > self.color = color
    >
    > def testit():
    > GenericWindow('foo', width=100, height=100, color=self.color)
    >
    > def suite():
    > s = unittest.Suite()
    > BrownWindowTest = functools.partial(TestGenericWindow, color='brown')
    > BlueWindowTest = functools.partial(TestGenericWindow, color='blue')
    > GreenWindowTest = functools.partial(TestGenericWindow, color='green')
    > s.addTest(unittest.makeSuite(BrownWindowTest))
    > s.addTest(unittest.makeSuite(BlueWindowTest))
    > s.addTest(unittest.makeSuite(GreenWindowTest))
    > return s
    >
    > if __name__ == '__main__': #unittest.main()
    > unittest.main()
    >
    > That code gives the following:
    >
    > Traceback (most recent call last):
    > File "./functools.partial.py", line 32, in <module>
    > unittest.main()
    > File "/usr/lib/python2.6/unittest.py", line 816, in __init__
    > self.parseArgs(argv)
    > File "/usr/lib/python2.6/unittest.py", line 837, in parseArgs
    > self.test = self.testLoader.loadTestsFromModule(self.module)
    > File "/usr/lib/python2.6/unittest.py", line 559, in loadTestsFromModule
    > tests.append(self.loadTestsFromTestCase(obj))
    > File "/usr/lib/python2.6/unittest.py", line 550, in
    > loadTestsFromTestCase
    > return self.suiteClass(map(testCaseClass, testCaseNames))
    > TypeError: __init__() takes exactly 3 arguments (2 given)
    >
    > Thanks for having a look,
    > Joel


    By default unittest.main() looks for subclasses of unittest.TestCase and
    generates test cases for every method that starts with "test". From that
    point of view suite() is just an ordinary function and will not even be
    called. There are a lot more problems with your code that suggest that you
    should carefully read the unittest documentation, and maybe even have a look
    at its source code.

    Here's what became of your code when I tried to make it run:

    import unittest

    class GenericWindow:
    def __init__(self, name, width, height, color='white'):
    print('Name: %s, width: %d, height: %d, color: %s' % (name, width,
    height, color))

    class TestGenericWindow(unittest.TestCase):
    def __init__(self, methodName, color):
    unittest.TestCase.__init__(self, methodName)
    print('color: %s' % color)
    self.color = color

    def testit(self):
    GenericWindow('foo', width=100, height=100, color=self.color)

    def suite():
    return unittest.TestSuite([
    TestGenericWindow("testit", color="brown"),
    TestGenericWindow("testit", color='blue'),
    TestGenericWindow("testit", color='green'),
    ])

    if __name__ == '__main__':
    import sys
    argv = sys.argv[:]
    argv.insert(1, "suite")
    unittest.main(argv=argv)
    Peter Otten, Oct 6, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steven Bethard

    unittest.TestCase, lambda and __getitem__

    Steven Bethard, Sep 13, 2004, in forum: Python
    Replies:
    7
    Views:
    443
    Alex Martelli
    Sep 14, 2004
  2. Replies:
    2
    Views:
    443
  3. Paddy
    Replies:
    4
    Views:
    353
    Ian Kelly
    Mar 25, 2011
  4. Scott
    Replies:
    1
    Views:
    110
    Timothy Hunter
    Aug 20, 2005
  5. John O'Hagan

    Generator vs functools.partial?

    John O'Hagan, Jun 21, 2012, in forum: Python
    Replies:
    4
    Views:
    261
    John O'Hagan
    Jun 21, 2012
Loading...

Share This Page