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

Jiv*_*ara 13 python django unit-testing subclassing

我有一组测试用例,所有测试用例应完全相同,方法是"方法x是否返回现有文件的名称?"

我认为最好的方法是从TestCase派生的基类,它们都共享,并简单地将测试添加到该类.不幸的是,测试框架仍然试图为基类运行测试,它没有意义.

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

class OneTestCase(SharedTest):
    ...my tests are performed, and 'SharedTest.x()'...
Run Code Online (Sandbox Code Playgroud)

我试图破解检查只是跳过测试,如果它被调用基类的对象而不是像这样的派生类:

    class SharedTest(TestCase):
        def x(self):
            if type(self) != type(SharedTest()):
                ...do test...
            else:
                pass
Run Code Online (Sandbox Code Playgroud)

但得到了这个错误:

ValueError: no such test method in <class 'tests.SharedTest'>: runTest
Run Code Online (Sandbox Code Playgroud)

首先,我想要做任何优雅的建议.其次,虽然我真的不想使用type()hack,但我想理解为什么它不起作用.

Sam*_*lan 26

您可以使用mixin,因为测试运行器只运行继承自的测试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
Run Code Online (Sandbox Code Playgroud)

有关此工作原因的更多信息,请搜索python方法解析顺序和多重继承.

  • 我明白,什么让我感到困惑的是SharedTestMixin调用self.assertEquals时它既没有声明它也没有继承它. (5认同)

Man*_*dan 5

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

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
Run Code Online (Sandbox Code Playgroud)

这有点像黑客。可能有更好的方法来做到这一点,但我不确定如何做

更新

正如 sdolan所说, mixin 是正确的方法。为什么我之前没看到呢?

更新2

(阅读评论后)如果(1)超类方法可以避免黑客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):
    ...
Run Code Online (Sandbox Code Playgroud)