需要父类的python类装饰器在继承类时运行

时间:2015-08-19 22:12:49

标签: python pytest

我正在使用py.test(使用xdist)中使用unittest库的示例。

我有一个班级:

def on_platforms(platforms):
    def decorator(base_class):
        module = sys.modules[base_class.__module__].__dict__
        for i, platform in enumerate(platforms):
            d = dict(base_class.__dict__)
            d['desired_capabilities'] = platform
            name = "%s_%s" % (base_class.__name__, i + 1)
        module[name] = new.classobj(name, (base_class,), d)
return decorator

@on_platforms(browsers)
class BaseTest:
    def setUp(self):
        pass

这包含我需要在我将创建的所有测试类中运行的公共代码。在包含要运行的实际测试的文件中,我有:

from BaseTest.py import BaseTest
class FirstTest(BaseTest):
    def test_to_run(self):
        pass

然后我有一个主文件,它将导入所有测试类并在执行main.py文件时全部运行它们。

main.py:     进口单位测试     来自FirstTest.py导入FirstTest

if __name__ == "__main__":
    unittest.main()

最后,我尝试执行:

py.test main.py -n3 --boxed

但是,它会成功执行main.py,但不会运行任何测试。为什么测试没有运行?感谢。

1 个答案:

答案 0 :(得分:0)

我认为您想使用元类而不是装饰器来创建BaseClass的额外版本。将调用元类来创建由以后的代码创建的任何子类(而装饰器不会创建)。这意味着您将自动获得子类的副本。

import sys

browsers=['x','y','z']

class Meta(type):
    def __new__(meta, name, bases, dct):
        cls = type.__new__(meta, name, bases, dct)
        mod_dct = sys.modules[cls.__module__].__dict__
        if 'desired_capabilities' not in dct:
            for i, platform in enumerate(cls.platforms):
                sub_name = "%s_%s" % (name, i + 1)
                sub_cls = meta(sub_name, (cls,), {'desired_capabilities': platform})
                mod_dct[sub_name] = sub_cls
        return cls

class BaseTest(metaclass=Meta):  # metaclass code will create BaseTest_1, BaseTest_2, ...
    platforms = browsers
    def setUp(self):
        pass

class SubTest(BaseTest):  # metaclass code will create SubTest_1, SubTest_2, ...
    pass

这为元类使用Python 3语法。如果您正在使用Python 2,请继承object并使用__metaclass__类变量:

class BaseTest(object):
    __metaclass__ = Meta
    # ...

platforms类属性将由BaseTest的子类继承(尽管它们可以使用自己的列表覆盖它),并且元类将为它们创建额外的子类。需要if 'desired_capabilities' not in dct测试来确保元类创建的特定于平台的子类不会递归地获取它们自己的子类。