在基类中定义不应直接实例化的测试方法

问题描述 投票:0回答:1

我正在尝试创建仅因登录的用户而异的测试用例。 因此,我认为在基类中定义测试并创建在

setUp()
期间登录用户的子类将是可行的方法。

但是我找不到一个优雅的解决方案来排除基类中的测试运行。

from django.contrib.auth.models import User
from django.test import TestCase


class A(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.user_a = User.objects.create_user("a", "", "a")
        cls.user_b = User.objects.create_user("b", "", "b")

    def setUp(self):
        # global set up stuff here
        ...

    def test_1(self):
        self.assertEqual(self.user_a.username, "a")


class SubA(A):
    def setUp(self):
        super().setUp()
        self.client.force_login(self.user_a)


class SubB(A):
    def setUp(self):
        super().setUp()
        self.client.force_login(self.user_b)

在上面的代码中,我只想运行类

SubA
SubB
中的继承测试,而不是
A
中的测试。

我已经尝试过:

  • 将基类提取到另一个模块,默认搜索模式不包含该模块。 => 仍然运行测试,因为必须导入基类才能继承它
  • 在包中定义一个
    load_tests(...)
    函数,不包括基类 => 与上面相同的结果
  • 在基类
    unittest.SkipTest
    中提高
    setUp()
    并在子类
    setUp
    中捕获它 => 有效,但将基类中的所有测试添加为“跳过”

所以我的问题是: 有没有办法排除基类中的测试(必须从 Django 的

TestCase
继承)运行而不将它们记录为跳过,并且最好不需要我的
./manage.py test
命令的附加参数?

python django python-unittest django-testing
1个回答
0
投票

我不知道答案,但有两种调查途径:

A - 将测试放入 mixin 类中:

class A(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.user_a = User.objects.create_user("a", "", "a")
        cls.user_b = User.objects.create_user("b", "", "b")

    def setUp(self):
        # global set up stuff here

class CommonTests( object):
    def test_1(self):
        self.assertEqual(self.user_a.username, "a")

class SubA( CommonTests, A):
    def setUp(self):
        super().setUp()
        self.client.force_login(self.user_a)
...

B - 使用测试框架的 subTest 工具

class A(TestCase):
    ... # setups as before

    def Test1( self):
        for user in ( self.user_a, self.user_b):
            with self.subTest( user=user):
                self.client.force_login(self.user_a)

                # and now the test(s) that you want to execute both for user_a and user_b
                self.assertEqual(user.username, "a")

如果子测试失败,包含该子测试的测试不会停止,并且迭代中的下一个子测试将开始。 self.subTest 的 kwarg 作为子测试失败消息的一部分打印。如果(如此处)传递的实体不是字符串,则会将其转换为 str。如果这会失败或生成愚蠢的输出,您将进行自己的转换,例如

self.subTest( user=f"{user.username} (pk={user.pk})" )

© www.soinside.com 2019 - 2024. All rights reserved.