Почему django TestCase не создает тестовую базу данных?

Я пишу тест Django, наследующий от django.test.TestCase. Везде, в документации, это руководство и даже в этом принятом SO принятый ответ указано, что при использовании Django TestCase автоматически создается тестовая БД. Раньше я работал с DRF APITestCases, и все работало хорошо. Здесь я использую очень стандартный подход, но метод класса setUpTestData использует мою производственную базу данных.

Что я делаю неправильно и что нужно сделать, чтобы тестовая БД создавалась и использовалась для теста? Пожалуйста, смотрите мой код ниже.

from django.test import TestCase
from agregator.models import AgregatorProduct
from django.db.models import signals

def sample_product_one():
    sample_product_one = {
        # "id": 1,
        "name": "testProdOne",
        "dph": 21,
        "updated": datetime.now(),
        "active": True,
        "updatedinstore": False,
        "imagechanged": False,
        "isVirtualProduct": False,
        }
    return sample_product_one


class TestCreateProdToCategory(TestCase):
    """
    Test for correct creation of records
    """

    @classmethod
    @factory.django.mute_signals(signals.pre_save, signals.post_save)
    def setUpTestData(cls):
        AgregatorProduct.objects.create(
            **sample_product_one()
        )


    def test_create_prod_to_cat(self):
        product = AgregatorProduct.objects.get(id=1)
        self.assertEqual(product.id, 1)

БД настроена:

DATABASES = {
    'agregator': {
        'NAME': 'name',
        'ENGINE': 'sql_server.pyodbc',
        'HOST': 'my_ip',
        'USER': 'my_user',
        'PASSWORD': 'my_pwd',
        'OPTIONS': {
            'driver': 'ODBC Driver 17 for SQL Server',
            'isolation_level': 'READ UNCOMMITTED',
        },
    }
}

Результаты теста в

----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\xevos\xevosadmin\agregator\tests\test_admin_actions\test_products_to_categories_admin_action.py", line 64, in test_create_prod_to_cat
    product = AgregatorProduct.objects.get(id=1)
  File "C:\xevos\xevosadmin\.venv\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\xevos\xevosadmin\.venv\lib\site-packages\django\db\models\query.py", line 397, in get
    raise self.model.DoesNotExist(
agregator.models.AgregatorProduct.DoesNotExist: AgregatorProduct matching query does not exist.

----------------------------------------------------------------------

что является результатом автоинкремента идентификатора и, учитывая, что в производственной базе данных уже есть продукты, он получает идентификатор, например, 151545 (AgregatorProduct matching query does not exist. является результатом того факта, что продукт, который раньше имел идентификатор = 1, был удален давным-давно в производство БД.)

Таким образом, тест записывает в существующую базу данных, и данные сохраняются там даже после завершения теста.


person David Louda    schedule 30.03.2021    source источник
comment
Можете ли вы показать конфигурацию вашей базы данных из настроек проекта Django? Кроме того, что происходит прямо сейчас? Возникает ли ошибка или тесты записываются в вашу нетестовую базу данных?   -  person GwynBleidD    schedule 30.03.2021
comment
Добавлено редактирование @GwynBleidD   -  person David Louda    schedule 30.03.2021
comment
Поскольку интеграция с сервером MSSQL является надстройкой стороннего производителя, она может не поддерживать создание тестовой базы данных. У меня нет возможности проверить это наверняка, так как существует множество пакетов, обеспечивающих такую ​​поддержку, использующих одно и то же имя движка, поэтому вам придется проверить это самостоятельно. Убедитесь, что вы проверили точную версию интеграции, которую вы используете.   -  person GwynBleidD    schedule 30.03.2021
comment
Кроме того, как вы проводите свои тесты? Если вы не используете ./manage.py test, может потребоваться дополнительная осторожность, чтобы вся подготовка к тесту в Django работала правильно.   -  person GwynBleidD    schedule 30.03.2021
comment
Я запускаю его py manage.py test, что должно быть таким же. Я действительно не думаю, что это связано с самой базой данных, потому что нет ничего, что указывало бы на то, что Django пытался ее создать. Это идет непосредственно для производства db   -  person David Louda    schedule 30.03.2021
comment
Если механизм базы данных не поддерживает создание тестовой базы данных для вас или не информирует вас о сбое, Django ничего не может с этим поделать. Как я уже сказал, я не уверен, что это так, но никто, кроме вас, не может это проверить и без информации, какую именно реализацию движка MSSQL вы используете.   -  person GwynBleidD    schedule 30.03.2021


Ответы (1)


Чтобы создать тестовую базу данных, используйте метод setUp внутри TestCase и запустите его с помощью теста python manage.py.

from django.test import TestCase
from myapp.models import Animal

class AnimalTestCase(TestCase):
    def setUp(self):
        Animal.objects.create(name="lion", sound="roar")
        Animal.objects.create(name="cat", sound="meow")

    def test_animals_can_speak(self):
        """Animals that can speak are correctly identified"""
        lion = Animal.objects.get(name="lion")
        cat = Animal.objects.get(name="cat")
        self.assertEqual(lion.speak(), 'The lion says "roar"')
        self.assertEqual(cat.speak(), 'The cat says "meow"')

База данных будет создана и удалена автоматически после выполнения тестов https://docs.djangoproject.com/en/3.1/topics/testing/overview/#writing-tests

person Vitor Ramalho    schedule 30.03.2021
comment
Спасибо за предложение, но метод setUp делает то же самое, что и метод setUpTestData, за исключением того, что setUpTestData запускается только один раз для настройки сцены, а не для каждого подтеста, поэтому приводит к той же ошибке. - person David Louda; 30.03.2021