从super调用所有子类方法?

时间:2013-06-14 14:36:26

标签: python python-unittest

我目前正在为我公司的构建脚本实施一些单元测试。为了消除膨胀并使其更容易实现新测试,我将使所有测试类继承自名为BasicTest的自定义子类,该子类继承自PyUnit的TestCase。

目前所有测试都使用了BasicTest中的两个函数:构造函数(虽然显然可能在将来被覆盖)和runTest()方法,它是超级构造函数的默认方法名称如果没有传入值,则使用(例如BasicTest()将创建一个在调用时执行runTest()方法的测试,而BasicTest('Foo')将使用Foo()方法。 / p>

我想让runTest()简单地从调用它的继承对象中运行所有可能的测试。但是,由于runTest()仅在BasicTest中定义并由子类继承,我正在寻找一种从super动态调用所有子类'方法的方法。我知道这违反了面向对象编程的规则,但从我所看到的情况来看,Python从来就不是一个遵循规则的人:)

为清楚起见,以下说明了我的意图:

我希望从子类对象调用runTest()并仅处理该对象的方法。让我们说SubclassTest()有方法TestParse()TestExec()。我想这样:

sub = SubClassTest() 
sub.runTest() 

运行TestParse()TestExec(),但我希望runTest()方法在BasicTest中定义并继承,而不会被覆盖。

2 个答案:

答案 0 :(得分:2)

可以创建元类,它将所有有趣的子类方法收集到类属性

class TestMetaclass(type):
    def __new__(cls, name, bases, attrs):
        own_tests = [v for k,v in attrs.iteritems() if k.startswith('test')]
        attrs['test_method_list'] = own_tests
        return super(TestMetaclass, cls).__new__(cls, name, bases, attrs)

将此元类设置为基类__metaclass__ 并实施runTests方法

class BaseTest():
    test_method_list = []
    __metaclass__ = TestMetaclass
    def runTests(self):
        for method in self.test_method_list:
            method(self)

在此之后,将使用此元类构建所有子类

class TestOne(BaseTest):
    def test_foo(self):
        pass

最后,可以使用运行runTests()方法

的收集方法
TestOne().runTests()

答案 1 :(得分:1)

示例代码: 将基类.py文件作为模块加载 并检查

import inspect
import imp
imp.load_source((name of class by which to want that module), (path base class name of file).py)
module = __import__((name of class by which to want that module))

inspect.getmembers(module) will give you dict of name, cls

希望这有帮助