我的测试框架目前基于测试运行器实用程序,该实用程序本身源自Eclipse pydev python test-runner。我正在转向使用Nose,它具有我自定义测试运行器的许多功能,但似乎是质量更好的代码。
我的测试套件包括许多以前从未运行过的抽象测试类。标准的python testrunner(和我的自定义的)只运行了unittest.TestCase和unittest.TestSuite的实例。
我注意到,自从我切换到Nose之后,它正在运行任何以名称“test”开头的东西,这很烦人......因为我们用于test-mixins的命名约定看起来像是Nose的测试类。以前这些从未作为测试运行,因为它们不是TestCase或TestSuite的实例。
显然,我可以重新命名方法,从名称中排除“test”这个词......这需要一段时间,因为测试框架非常大并且有很多继承。另一方面,如果有一种方法可以让Nose只看到TestCases和TestSuites是可运行的......那就没有别的了。
可以这样做吗?
答案 0 :(得分:6)
您可以尝试使用-m
的{{1}}选项。来自文档:
测试类是在a中定义的类 与testMatch匹配的测试模块 是unittest.TestCase的子类
nosetests
设置-m
,这样您就可以禁用以 test 开头的任何内容进行测试。
另一件事是您可以将testMatch
添加到测试用例类声明中,以将其标记为“不是测试”。
答案 1 :(得分:2)
如果你想要一个真正抽象的测试类,你可以从object继承抽象类,然后在测试用例中继承。
例如:
class AbstractTestcases(object):
def test_my_function_does_something(self):
self.assertEquals("bar", self.func())
然后将其用于:
class TestMyFooFunc(AbstractTestcases, unittest.TestCase):
def setUp(self):
self.func = lambda: "foo"
然后nosetests
将只选择TestMyFooFunc
中的测试用例而不是AbstractTestCases
中的测试用例。
答案 2 :(得分:0)
您可以使用nose的--attr参数来指定由unittest.TestCase构成的属性。例如,我使用:
nosetests --attr="assertAlmostEqual"
使用和以及或匹配可以更加小心:
nosetests -A "assertAlmostEqual or addTest"
有关方法/属性的完整列表,请参阅unittest's documentation,并查看Nose的description of the capabilities of the --attr plugin。
答案 3 :(得分:0)
@nailxx答案的一个附录:
您可以在父类中设置location <- c(rep(c("c01", "c02", "c03", "c04", "c05"), each = 5))
condition1 <- c(0,0,0,0,0,1,1,0,2,5,1,0,0,5,4,0,0,0,0,0,0,0,5,1,0)
condition2 <- c(0,0,0,0,0,5,6,0,5,0,0,4,7,3,8,0,0,0,0,0,3,0,5,0,7)
condition3 <- c(0,0,0,0,0,4,3,0,0,0,0,4,7,9,2,0,0,0,0,0,0,0,5,1,5)
my_df <- data.frame(location, condition1, condition2, condition3)
,然后使用元类(请参阅This question并附带一些精彩的解释),以便在进行子类化时将其设置为True。
(最后,我找到了使用元类的借口!)
虽然__test__ = False
是双下划线属性,但我们必须将其显式设置为__test__
,因为不设置它会导致python只是在MRO的上方查找属性并进行评估它到True
。
因此,我们需要在类实例化中检查其中一个父类是否具有False
。如果是这种情况并且当前的类定义本身没有设置__test__ = False
,我们将__test__
添加到属性dict。
结果代码如下所示:
'__test__': True
可以将此扩展为一些更隐式的行为,例如“如果名称以class TestWhenSubclassedMeta(type):
"""Metaclass that sets `__test__` back to `True` when subclassed.
Usage:
>>> class GenericTestCase(TestCase, metaclass=TestWhenSubclassed):
... __test__ = False
...
... def test_something(self):
... self.fail("This test is executed in a subclass, only.")
...
...
>>> class SpecificTestCase(GenericTestCase):
... pass
"""
def __new__(mcs, name, bases, attrs):
ATTR_NAME = '__test__'
VALUE_TO_RESET = False
RESET_VALUE = True
values = [getattr(base, ATTR_NAME) for base in bases
if hasattr(base, ATTR_NAME)]
# only reset if the first attribute is `VALUE_TO_RESET`
try:
first_value = values[0]
except IndexError:
pass
else:
if first_value == VALUE_TO_RESET and ATTR_NAME not in attrs:
attrs[ATTR_NAME] = RESET_VALUE
return super().__new__(mcs, name, bases, attrs)
开头,自动设置Abstract
”,但为了清晰起见,我会保留明确的分配。
让我粘贴简单的单元测试来演示行为 - 并提醒每个人在引入功能后应花两分钟时间测试代码。
__test__ = False
答案 4 :(得分:0)
您还可以在测试用例级别使用多重继承,并让基类仅从object
继承。见this thread:
class MyBase(object):
def finishsetup(self):
self.z=self.x+self.y
def test1(self):
self.assertEqual(self.z, self.x+self.y)
def test2(self):
self.assert_(self.x > self.y)
class RealCase1(MyBase, unittest.TestCase):
def setUp(self):
self.x=10
self.y=5
MyBase.finishsetup(self)
class RealCase2(MyBase, unittest.TestCase):
def setUp(self):
self.x=42
self.y=13
MyBase.finishsetup(self)