【问题标题】:Django: How to get setUpTestData to run once for all tests?Django:如何让 setUpTestData 为所有测试运行一次?
【发布时间】:2019-12-03 11:34:52
【问题描述】:

我正在运行 django + django_tenants + django_restframework。在多租户环境中,每个模式的租户表中都需要有一个实例——在我的测试中,这意味着“public”、“test”和“test2”。

需要为所有测试创建这些租户及其相应的架构。这些实例中的数据不会改变,所以我想在测试运行开始时执行一次,并且在此期间不会再次重复。

我从研究中学到的东西:

  • setUp() 在每个单独的测试之前运行
  • setUpClass() 在每个测试用例之前运行
  • setUpTestData() 在每个测试用例之前运行

我遇到的问题是,当我的第二组测试运行时,我在尝试创建租户/模式时遇到异常,因为它们已经存在。

我还在 Django 高级测试文档中找到了 setup_databases(),我想知道这是否适合...即它可以被子类化吗?

这是我的所有测试子类的基类...

class TenantTestCase(APITestCase):
    public_tenant = None
    test_tenant   = None
    test2_tenant  = None

    @classmethod
    def setUpClass(cls):
        cls.add_allowed_test_domain()
        cls.setUpTestData()

    @classmethod
    def setUpTestData(cls):
        print('run setUpTestData')

        cls.public_tenant = Tenant.create_tenant('Public')
        cls.test_tenant   = Tenant.create_tenant('Test')
        cls.test2_tenant  = Tenant.create_tenant('Test2')

        connection.set_tenant(cls.public_tenant)

我读到 setUpTestData() 应该在每个测试用例之前运行(如果从 django.test.testcase 子类化),但在我的情况下它没有运行。我必须将 cls.setUpTestData() 放入 setUpClass() 以使其运行。

这是我的一项测试的精简示例...

class TenantModelTests(TenantTestCase):

    def setUp(self):
        self.client = APIClient()
        super(TenantModelTests, self).setUp()

    def test_check_public_tenant(self):
        self.assertIsInstance(self.public_tenant, Tenant)

        self.assertEqual(self.public_tenant.name, 'Public', 'Public tenant name is not "Public".')
        self.assertEqual(self.public_tenant.subdomain, '', 'Public tenant subdomain is not blank.')
        self.assertEqual(self.public_tenant.schema_name, 'public', 'Public tenant schema_name is not "public".')

    def test_check_private_tenants(self):
        self.assertIsInstance(self.test_tenant, Tenant)

        self.assertEqual(self.test_tenant.name, 'Test', 'Test tenant name is not "Test".')
        self.assertEqual(self.test_tenant.subdomain, 'test', 'Test tenant subdomain is not "test".')
        self.assertEqual(self.test_tenant.schema_name, 'test', 'Test tenant schema_name is not "test".')

当我在两个不同的应用程序中使用两个测试文件运行此程序时,我看到两次“运行 setUpTestData” - 当然,我看到了“已经存在”的异常。那么我应该把应该在整个测试运行开始时运行一次的代码放在哪里呢?

【问题讨论】:

  • 这段时间你发现了吗?
  • @Soren,我/我们在发布这个问题后不久就搁置了我们项目的单元测试部分。我知道这对开发来说并不理想,但我们不得不做出一些艰难的选择:我们的时间表。在这一点上(几个月后),我不记得是否找到了解决方法。如果我这样做了,我猜这可能不是“Django 方式”。抱歉,我无法提供更具体的帮助。

标签: django unit-testing django-rest-framework multi-tenant


【解决方案1】:

setUpTestData 为 TestCase 调用一次。 如果数据库不支持事务,则每次测试运行前都会调用 setUpTestData。

更改您的setUpClass,不要直接致电setUpTestData。尝试用户 super()

@classmethod
def setUpClass(cls):
    cls.add_allowed_test_domain()
    super(TenantTestCase, cls).setUpClass()

参考: https://docs.djangoproject.com/en/1.11/topics/testing/tools/#testcase Note that if the tests are run on a database with no transaction support (for instance, MySQL with the MyISAM engine), setUpTestData() will be called before each test, negating the speed benefits.

【讨论】:

  • @K_K - 谢谢。它解决了 setUpTestData() 没有被自动调用的问题,但我帖子的真正问题是最后的问题:我应该把应该在整个测试运行开始时运行一次的代码放在哪里?
猜你喜欢
  • 1970-01-01
  • 2022-11-29
  • 2020-04-28
  • 1970-01-01
  • 2015-05-30
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
相关资源
最近更新 更多