是否可以使Nose只运行TestCase或TestSuite的子类(如unittest.main())

时间:2010-06-24 14:37:53

标签: python unit-testing nose

我的测试框架目前基于测试运行器实用程序,该实用程序本身源自Eclipse pydev python test-runner。我正在转向使用Nose,它具有我自定义测试运行器的许多功能,但似乎是质量更好的代码。

我的测试套件包括许多以前从未运行过的抽象测试类。标准的python testrunner(和我的自定义的)只运行了unittest.TestCase和unittest.TestSuite的实例。

我注意到,自从我切换到Nose之后,它正在运行任何以名称“test”开头的东西,这很烦人......因为我们用于test-mixins的命名约定看起来像是Nose的测试类。以前这些从未作为测试运行,因为它们不是TestCase或TestSuite的实例。

显然,我可以重新命名方法,从名称中排除“test”这个词......这需要一段时间,因为测试框架非常大并且有很多继承。另一方面,如果有一种方法可以让Nose只看到TestCases和TestSuites是可运行的......那就没有别的了。

可以这样做吗?

5 个答案:

答案 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)