Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何向一组Django TestCase派生类添加测试方法?_Python_Django_Unit Testing_Subclassing - Fatal编程技术网

Python 如何向一组Django TestCase派生类添加测试方法?

Python 如何向一组Django TestCase派生类添加测试方法?,python,django,unit-testing,subclassing,Python,Django,Unit Testing,Subclassing,我有一组测试用例,所有测试用例都应该完成完全相同的测试,就像“MethodX是否返回现有文件的名称?” 我认为最好的方法是从它们共享的TestCase派生一个基类,然后简单地将测试添加到该类中。不幸的是,测试框架仍然试图为基类运行测试,这是没有意义的 class SharedTest(TestCase): def x(self): ...do test... class OneTestCase(SharedTest): ...my tests are perfo

我有一组测试用例,所有测试用例都应该完成完全相同的测试,就像“MethodX是否返回现有文件的名称?”

我认为最好的方法是从它们共享的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
ValueError:runTest中没有此类测试方法

首先,我想知道做这件事的一些优雅的建议。第二,虽然我不想使用type()hack,但我想了解它为什么不起作用。

我也遇到了类似的问题。我无法阻止基类中的测试方法被执行,但我确保它不会执行任何实际代码。我通过检查属性并在设置后立即返回来实现这一点。该属性仅为基类设置,因此测试在基类以外的任何地方运行

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,混入是正确的方法。为什么我以前没看到

更新2

(阅读评论后)如果(1)超类方法可以避免hackish
if getattr(self'do\u not\u run',False):
check;(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):
    ...

通过利用测试运行程序只运行继承自
unittest.TestCase
(Django的
TestCase
继承自)的测试,可以使用mixin。例如:

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方法解析顺序和多重继承。

感谢您的回复,我是这样开始的,不喜欢我有一个类调用它没有的方法。Pylint对此也很恼火,我大量使用Pylint。@jivanamara:您不需要在
TestOne
TestTwo
测试类中调用
test\u common
。它是“混合”的,因为它通过多重继承成为类的一部分。@Manoj,我同意,这是一个很好的解决方案+1我明白,当self.assertEquals既不声明也不继承它时,让我感到困扰的是SharedTestMixin调用self.assertEquals。因为你没有在SO上询问过它:)这是我在提问后编写的代码。这是一个有点黑客,但派林更喜欢它,我不认为它显着比混音更糟糕。唯一不好的一面是,它在测试计数中增加了一个不存在的测试…这不会让我晚上睡不着觉。因为我不太熟悉Mixin的哲学,我从一个朋友那里得到了这一点,他证实了我的犹豫;说混合器应该是独立的。我使用这个解决方案,因为mixin解决方案使mixin依赖于将使用它的类。这很好,但我似乎无法控制测试运行的顺序(这似乎违反直觉)。使用上述代码,OneTestCase中的所有代码都会在SharedTest代码运行之前运行。我的OneTestCase依赖于SharedTest。有没有办法控制这一点?一个建议(我没有尝试过)是在共享测试中添加一个decorator来检查self。在运行测试之前,类不等于SharedTest。但是mixin可能是更干净的方法。@jivanamara:有一种方法可以避免超级类测试方法被计数,并且在编写测试方法时不使用
if getattr(…)
检查。请参阅我答案的第二次更新。