1

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

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

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

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

我想runTest()从子类对象中调用并且只处理该对象的方法。假设SubclassTest()有方法TestParse()TestExec(). 我想要这样:

sub = SubClassTest() 
sub.runTest() 

运行TestParse()and TestExec(),但我希望在不被覆盖的情况下runTest()定义和继承该方法。BasicTest

4

2 回答 2

3

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

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()
于 2013-06-14T16:03:12.313 回答
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

希望这可以帮助

于 2013-06-14T14:51:21.080 回答