Ben Finney wrote:
Ethan Furman <et...@stoneleaf.us> writes:

Here we have django's TestCase that does *not* want to call
unittest2.TestCase (assuming that's not a bug), but it gets called
anyway because the Mixin3 sibling has it as a base class.  So does
this mean that TestCase and Mixin3 just don't play well together?

Maybe composition instead of inheritance is the answer (in this case,
anyway ;).

TestCase subclasses is a multiple-inheritance use case that I share. The
mix-ins add test cases (methods named ‘test_’ on the mix-in class) to
the TestCase subclass. I would prefer not to use multiple inheritance
for this if it can be achieved in a better way.

How can composition add test cases detectable by Python's ‘unittest’?

Metaclasses, if's that an option...

8<-------------------------------------------------------------
import unittest
from composite import Composite  # python 3 only

class Spam():
    def test_spam_01(self):
        print('testing spam_01')
    def test_spam_02(self):
        print('testing spam_02')

class Eggs():
    def test_eggs_01(self):
        print('testing eggs_01')
    def test_eggs_02(self):
        print('testing eggs_02')

class TestAll(
        unittest.TestCase,
        metaclass=Composite,
        parts=(Spam, Eggs)):
    def setUp(self):
        print('Setting up...')
    def tearDown(self):
        print('Tearing down...')
    def test_something(self):
        print('testing something')

if __name__ == '__main__':
    unittest.main()
8<-------------------------------------------------------------

or a class decorator

8<-------------------------------------------------------------
class Compose(object):  # python 3 only
    def __init__(self, *parts):
        self.parts = parts
    def __call__(self, func):
        for part in self.parts:
            for attr in dir(part):
                if attr[:2] == attr[-2:] == '__':
                    continue
                setattr(func, attr, getattr(part, attr))
        return func

import unittest

class Spam():
    def test_spam_01(self):
        print('testing spam_01')
    def test_spam_02(self):
        print('testing spam_02')

class Eggs():
    def test_eggs_01(self):
        print('testing eggs_01')
    def test_eggs_02(self):
        print('testing eggs_02')

@Compose(Spam, Eggs)
class TestAll(unittest.TestCase):
    def setUp(self):
        print('Setting up...')
    def tearDown(self):
        print('Tearing down...')
    def test_something(self):
        print('testing something')

if __name__ == '__main__':
    unittest.main()
8<-------------------------------------------------------------

The decorator, as written, doesn't work on py2, and doesn't do any error checking (so overwrites methods in the final class) -- but I'm sure it could be spiffed up.

~Ethan~
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to