我正在使用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,但不会运行任何测试。为什么测试没有运行?感谢。
答案 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
测试来确保元类创建的特定于平台的子类不会递归地获取它们自己的子类。