Django:如何让 setUpTestData 为所有测试运行一次?

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

我正在运行 django + django_tenants + django_restframework。在 Multi-Tenancy 环境中,每个模式的租户表中都需要有一个实例 - 在我的测试中,这意味着“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".')

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

最佳答案

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 请注意,如果测试在不支持事务的数据库上运行(例如,带有 MyISAM 引擎的 MySQL),将在每次测试之前调用 setUpTestData(),从而抵消速度优势。

关于Django:如何让 setUpTestData 为所有测试运行一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57197742/

相关文章:

python - Django 导入错误 : cannot import name 'x'

java - 在 Java 中为继承的类编写单元测试

python - 如何在 Django 中从 postgresql 迁移到 sqlite3?

django - 我应该在 Django 中测试我的通用 DetailView

python - Django Rest Framework-在POST上创建外键对象

django - 如何在django_rest_framework APIView中配置ID参数

python - django-allauth:检查用户是否使用社交帐户注册

python - 如何从嵌套的 json 值中提取特定值。?

python - Django:导入错误:没有名为 social.apps.django_app 的模块

c# - Visual Studio 单元测试 C# 的命令行参数