Django 测试模型实例设置

Django testing model instance setup

为什么将实例创建为 class 属性:

class ModelTestsProducts(TestCase):
    # Create example objects in the database

    product_category = models.Product_category.objects.create(
            name='Spring'
        )
    product_segment = models.Product_segment.objects.create(
            name='PS1',
            product_category=self.product_category
        )
    product_group = models.Product_group.objects.create(
            name='PG1',
            product_segment=self.product_segment
        )
    def test_product_category(self):
        self.assertEqual(str(self.product_category), self.product_category.name)
    def test_product_segment(self):
        self.assertEqual(str(self.product_segment), self.product_segment.name)
    def test_product_group(self):
        self.assertEqual(str(self.product_group), self.product_group.name)

我在第二次 运行ning 测试时遇到以下错误?

django.db.utils.IntegrityError: duplicate key value violates unique constraint "products_product_category_name_key"
DETAIL:  Key (name)=(dadsad) already exists.

当我使用 setUp 方法然后在这个 setUp 方法中创建对象时它工作正常,但我不明白为什么上面的方法以某种方式多次创建每个对象并因此失败了唯一约束在模型中设置。 是不是因为 django 测试套件每次每个测试函数都是 运行 时都会以某种方式调用这个 class,因此每个属性都被分配了多次?

但是如果我将对象分配移动到 class 之外(在测试文件中),那么我也会得到这个 duplicate error,所以这意味着整个测试文件每次都会被多次调用时间测试正在进行 运行.

还有一件事我使用 docker 来 运行 这个 Django 应用程序和 运行 来自 docker-compose 命令的 django 测试。

如果您使用的是 Django 的 TestCase,Django 将 运行 在单独的事务中进行每个测试,测试完成后将回滚,这意味着不会有任何更改您的数据库和您尝试 运行 的所有内容都将只存在于您的测试中。这样做是为了确保您的测试不会相互影响。

setUp 函数也在该事务中执行,并且在您的测试 class 中的每个测试之前调用它。但是你 运行 在那个函数之外的所有东西,在你的情况下在 class 主体中,都不会包含在这样的事务中,所以它不会在你的测试之间回滚。如果这段代码被执行了两次(测试 运行ner 可能会在幕后完成),您的代码将尝试在数据库中创建一些已经存在的数据,但它会失败。

如果您想对测试的执行方式进行一些优化,您可以使用 setUpTestData,这样您的测试数据只对单个测试中的所有测试初始化​​一次 class。它将被包裹在一个外部 shell 事务中,并在完成此类测试用例的所有测试后回滚。