如何让nose查找基类测试类中定义的类属性?
我正在进行一些针对数据库的集成测试,我希望有一个像这样的结构:
class OracleMixin(object):
oracle = True
# ... set up the oracle connection
class SqlServerMixin(object):
sql_server = True
# ... set up the sql server connection
class SomeTests(object):
integration = True
# ... define test methods here
class test_OracleSomeTests(SomeTests, OracleMixin):
pass
class test_SqlServerSomeTests(SomeTests, SqlServerMixin):
pass
这样,我就可以分别运行SQL Server的测试和Oracle的测试,方法是:
nosetests -a oracle
nosetests -a sql_server
或者可以这样运行所有的集成测试:
nosetests -a integration
不过,看起来nose只会查找子类上的属性,而不会查找基类上的属性。因此,我必须这样定义测试类,否则测试就无法运行:
class test_OracleSomeTests(SomeTests, OracleMixin):
oracle = True
integration = True
class test_SqlServerSomeTests(SomeTests, SqlServerMixin):
sql_server = True
integration = True
这样维护起来有点麻烦。有没有什么办法可以解决这个问题?如果我只处理一个基类,我可以使用元类并在每个类上定义属性。但是我对为测试类、Oracle和SQL Server各自使用一个元类这件事有点不安。
2 个回答
0
如果你想找到一个在父类中定义的属性,而在子类中有一个同名的属性,你需要加上父类的名字来访问你想要的那个属性。
我觉得这就是你想要的:
class Parent:
prop = 'a property'
def self_prop(self):
print self.prop
# will always print 'a property'
def parent_prop(self):
print Parent.prop
class Child(Parent):
prop = 'child property'
def access_eclipsed(self):
print Parent.prop
class Other(Child):
pass
>>> Parent().self_prop()
"a property"
>>> Parent().parent_prop()
"a property"
>>> Child().self_prop()
"child property"
>>> Child().parent_prop()
"a property"
>>> Child().access_eclipsed()
"a property"
>>> Other().self_prop()
"child property"
>>> Other().parent_prop()
"a property"
>>> Other().access_eclipsed()
"a property"
在你的情况下,看起来你有两个不同的类,它们定义了不同的变量,所以你可以在你的测试函数的开头或者初始化的时候加一个尝试:捕获:的结构。
然后说
try:
isSQLServer = self.sql_server
except AttributeError:
isSQLServer = False
(不过其实它们应该定义相同的变量,这样测试类就不需要了解子类的任何信息了)
4
我觉得你可能需要自己写一个插件,因为现有的attrib插件里的代码只关注类的__dict__
。这里有个代码。
def wantClass(self, cls):
"""Accept the class if the class or any method is wanted.
"""
cls_attr = cls.__dict__
if self.validateAttrib(cls_attr) is not False:
return None
...
你可以尝试修改这个插件,做一些类似的事情(不过我没有测试过)。
def wantClass(self, cls):
"""Accept the class if the class or any method is wanted.
"""
for class_ in cls.__mro__:
cls_attr = class_.__dict__
if self.validateAttrib(cls_attr) is not False:
return None
cls_attr = cls.__dict__
...
不过,我不确定这样做到底比使用元类的方式好还是不好。