2010-08-31 50 views
9

我有一组测试用例,都应该完成相同的测试,沿着“方法x返回现有文件的名称?”的行。如何将测试方法添加到一组Django TestCase派生类?

我认为最好的方法是从TestCase派生出来的基类,它们都共享,并且简单地将测试添加到该类中。不幸的是,测试框架仍然试图对基类进行测试,但没有任何意义。

class SharedTest(TestCase): 
    def x(self): 
     ...do test... 

class OneTestCase(SharedTest): 
    ...my tests are performed, and 'SharedTest.x()'... 

我想在一个检查,以破解简单地跳过测试,如果它被称为基类对象上,而不是派生类是这样的:

class SharedTest(TestCase): 
     def x(self): 
      if type(self) != type(SharedTest()): 
       ...do test... 
      else: 
       pass 

,但得到这个错误:

ValueError: no such test method in <class 'tests.SharedTest'>: runTest 

首先,我想要这样做的任何优雅的建议。其次,虽然我不想使用type()入侵,但我想了解为什么它不起作用。

+0

@jivanamara:有一种方法可以避免超类测试方法被计数_and_在没有'if getattr(...)'检查的情况下编写测试方法。看到我的答案的第二个更新。 – 2010-09-01 15:45:57

回答

1

我遇到过类似的问题。我无法阻止正在执行的基类中的测试方法,但我确保它没有执行任何实际的代码。我通过检查属性并在设置后立即返回。这个属性只是为Base类设置的,因此除了基类之外,其他地方的测试都运行了。

class SharedTest(TestCase): 
    def setUp(self): 
     self.do_not_run = True 

    def test_foo(self): 
     if getattr(self, 'do_not_run', False): 
      return 
     # Rest of the test body. 

class OneTestCase(SharedTest): 
    def setUp(self): 
     super(OneTestCase, self).setUp() 
     self.do_not_run = False 

这是一个黑客。有 大概 更好的方法做到这一 但我不知道如何

更新

由于sdolan says一个mixin是正确的方式。为什么我以前没有看到?

更新2

这将是很好,如果(1)超类方法能够避免的hackish if getattr(self, 'do_not_run', False):检查(阅读评论后); (2)如果测试数量准确计数。

有一种可能的方法来做到这一点。 Django选取并执行tests中的所有测试类,无论是tests.py还是带有该名称的软件包。如果测试超类之外被声明为测试模块,那么这将不会发生。它仍然可以被测试类继承。例如SharedTest可以位于app.utils然后由测试用例使用。这将是上述解决方案的更清晰版本。

# module app.utils.test 
class SharedTest(TestCase): 
    def test_foo(self): 
     # Rest of the test body. 

# module app.tests 
from app.utils import test 
class OneTestCase(test.SharedTest): 
    ... 
+0

因为你没有问过这个问题:) – sdolan 2010-08-31 07:05:44

+0

这就是我提出问题后编写的。这有点破解,但pylint更喜欢它,我没有看到它比mixin差得多。唯一不利的一面是它增加了一个不存在的测试计数......这不会让我在晚上保持身材。 – JivanAmara 2010-09-01 09:18:19

+0

因为我对mixin的哲学不是很熟悉,所以我把它从朋友那里拿走了,他证实了我的遗憾;说mixin应该是独立的。由于mixin解决方案使mixin依赖于将使用它的类,因此我将使用此解决方案。 – JivanAmara 2010-09-01 09:41:25

22

你可以通过利用使用混入了测试运行仅运行测试从unittest.TestCase继承例如(其中Django的TestCase继承。):

class SharedTestMixin(object): 
    # This class will not be executed by the test runner (it inherits from object, not unittest.TestCase. 
    # If it did, assertEquals would fail , as it is not a method that exists in `object` 
    def test_common(self): 
     self.assertEquals(1, 1) 


class TestOne(TestCase, SharedTestMixin): 
    def test_something(self): 
     pass 

    # test_common is also run 

class TestTwo(TestCase, SharedTestMixin): 
    def test_another_thing(self): 
     pass 

    # test_common is also run 

欲了解更多关于为什么这个作品搜索python方法解析顺序和多重继承。

+0

+1。这是干净利落的方式。 – 2010-08-31 04:54:57

+0

感谢您的回复, 我是这样开始的,不喜欢我有一个叫做方法的类,它没有。 Pylint也吠叫了这一点,我大量使用pylint。 – JivanAmara 2010-08-31 05:38:12

+0

@jivanamara:你不需要在你的'TestOne'和'TestTwo'测试类中调用'test_common'。它是“混合在一起”的,因为它是通过多重继承而成为班级的一部分。 – sdolan 2010-08-31 06:17:16

相关问题