Django Unit Testing - Как протестировать все экземпляры в модели?

Я хочу проверить все экземпляры в БД с помощью Django.

У меня есть скрипт python, который заполняет БД, и я хочу проверить каждый экземпляр, прошел ли он тест.

Я предоставляю здесь фиктивный tests.py:

from django.test import TestCase
from app_core.models import Item
# Item model fields are: pk, first, second

class PairTestCase(TestCase):
    def setUp(self):
        # This script populates the DB creating several Item instances
        from app_core.init import init_items

    def test_pair_elems_different(self):
        """First and second fields MUST be different inside the instance"""
        item = Item.objects.get(pk=1)
        self.assertNotEqual(item.first, item.second)

Как видите, я только что протестировал один экземпляр. Предположим, что БД содержит 1000 экземпляров элементов, какой лучший способ протестировать их все?

Единственное решение, которое приходит мне в голову, это использование простого цикла FOR внутри test_pair_elems_different, итерация всех объектов и сравнение каждого экземпляра.

Правилен ли такой подход в контексте лучших практик/принципов модульного тестирования?

Мне кажется, вы смотрите на это не с той стороны.

Вы хотите убедиться, что first != second, верно? Предположительно, у вас есть ограничение на модель, и именно его вы проверяете.

Вам нужен тест, который пытается добавить запись, где эти 2 поля равны, затем проверить, что эта попытка вызывает соответствующую ошибку ограничения.

Я сам больше люблю pytest, но я думаю, что стандартный фреймворк unittest использует assertRaises для этого.

Когда вы убедились, что добавление записи с одинаковыми значениями недопустимо, нет необходимости проверять каждый экземпляр.

Вы можете сделать что-то вроде этого. Аннотируйте столбец if these two fields are equal и затем отфильтруйте по нему.
Это фактически будет проверять каждый отдельный элемент, но это не даст вам ошибку, как Item <230> failed validation, но даст вам общее Items Failed

from django.db.models import Q, F,  ExpressionWrapper, BooleanField

countOfEqual = Item.objects.annotate(
  equal=ExpressionWrapper(
    Q(first=F('second')),
    output_field=BooleanField()
)).filter(equal=True).count()

self.assertEqual(countOfEqual, 0, '{0} Items have matching first & second. This should be 0'.format(countOfEqual))

Если вам нужны конкретные предметы, которые не удались, вы можете, по крайней мере, отрезать .count() и фильтровать по списку - это сократит время, поскольку вы будете перебирать только те предметы, о которых уже знаете, что они плохие

Вернуться на верх