Мое приложение Django должно прочитать таблицы уже существующей базы данных. Таким образом, модели базы данных генерируются с использованием InspectDB
командование Они выглядят так:
class User(models.Model): first_name = models.CharField(max_length=255) second_name = models.CharField(max_length=255) # other properties class Meta: managed = False db_table = 'user'
управляемый
Свойство говорит Джанго не создавать таблицу как часть мигрировать
команда и не удалять его после Flush
Анкет Улов здесь в том, что Django не создаст таблицу во время тестирования. Поэтому, когда я хотел проверить свой код с базой данных о не продакшн, я столкнулся с следующими проблемами:
- Необходимость создавать все таблицы для неуправляемых моделей вручную только для запуска тестов. В противном случае я получал
django.db.utils. OperationalError: Нет такой таблицы: Пользователь
Анкет - Для меня не было очевидно, как генерировать светильники для неуправляемых моделей. Если модель управляется, вы можете запустить миграции в тестовой базе данных, заполнить таблицы с помощью
оболочка
командовать и сохранить его сDimpladata
Анкет Но таблицы неуправляемых моделей не создаются во время миграций, нет ничего населения. Опять же, мне пришлось создать все вручную.
Моя цель состояла в том, чтобы найти способ автоматизировать процесс, облегчая тестирование и сотрудничество. Соответствующие кусочки разбросаны по всему Интернету. Это попытка собрать их в одном месте.
Перед тем, как Test Runner запустит тесты, он запускает миграции, создавая таблицы для управляемых моделей. Сами миграции – это код Python, который создает модели и устанавливает управляемый
свойство. Можно изменить миграцию, чтобы она устанавливала управляемый
к Истинный
Пока мы тестируем и Ложный
в противном случае для не управляемых моделей. Для этого мы создадим Is_testing
переменная в настройки.py
и установите на Истинный
Когда мы тестируем. Мы также изменим код миграции:
from django.conf import settings # ... operations = [ migrations.CreateModel( name='User', fields=[ # ... ], options={ 'db_table': 'user', # 'managed': False, 'managed': settings.IS_TESTING, }, ), ]
Теперь таблица будет создана всякий раз, когда миграция запускается с Is_testing
Анкет Идея принадлежит Кайлу Валаду, который описал ее в своем блоге . Для создания приспособлений метод с оболочка
Команда, описанная ранее, будет работать. Недостатком здесь является то, что вы должны помнить, чтобы изменить миграцию каждой неуправляемой модели.
Более сложным решением является создание пользовательского тестового бегуна, который будет преобразовать все неуправляемые модели в управление, прежде чем провести тест, и впоследствии вернуть эффект. Мы поместим бегуна в appname/utils.py
:
from django.test.runner import DiscoverRunner class UnManagedModelTestRunner(DiscoverRunner): def setup_test_environment(self, *args, **kwargs): from django.apps import apps get_models = apps.get_models self.unmanaged_models = [m for m in get_models() if not m._meta.managed] for m in self.unmanaged_models: m._meta.managed = True super(UnManagedModelTestRunner, self).setup_test_environment(*args, **kwargs) def teardown_test_environment(self, *args, **kwargs): super(UnManagedModelTestRunner, self).teardown_test_environment(*args, **kwargs) for m in self.unmanaged_models: m._meta.managed = False
Теперь мы скажем Джанго использовать этого бегуна, добавив Test_runner
в наши настройки. Мы еще не готовы, потому что Пользователь
модель Имеет пользовательское название таблицы Пользователь
Анкет Вот почему нам нужно создать тестовые таблицы без запуска миграций. Есть Небольшое приложение для этого. Он установлен путем запуска PIP установка
и добавление в Insted_apps
Анкет Наши тесты будут работать, если мы запустим их с -n
выключатель: Python Manage.py Test -n
Анкет Как следствие, мы потеряем способность увидеть, сломается ли какая -либо из наших миграций (что, вероятно, хорошо, если все они генерируются Джанго).
Идея создания пользовательского тестового бегуна принадлежит Тобиасу Макналти, который разместил его в Блог CAKTUS GROUP Анкет Код из его поста должен был быть Обновлено .
Когда дело доходит до поддержания кода, есть осложнения. Во -первых, если бы мы хотели использовать какой -то другой тестовый бегун, нам придется унаследовать от него:
from django.test.runner import DiscoverRunner from django_nose import NoseTestSuiteRunner class UnManagedModelTestRunner(NoseTestSuiteRunner, DiscoverRunner): # ...
Во -вторых, даже если Django-test без миграции
Приложение просто, оно не значит Это не может быть сломано новой версией Django, поэтому мы должны быть готовы к устранению его устранения. В -третьих, мы должны генерировать светильники необычным образом. Таблицы наших неуправляемых моделей доступны только в setup ()
Метод, поэтому для создания приспособлений мы должны были бы добавить и сбрасывать данные В исходном коде теста:
import sys from django.core.management import call_command # ... def setUp(self): models.User.objects.create( # ... ) sysout = sys.stdout sys.stdout = open('fixtures/users.json', 'w') call_command('dumpdata', app_label='app_name') sys.stdout = sysout
После того, как мы запустили код, мы можем удалить его и загрузить приспособление в наших тестах обычный путь Анкет
Когда тесты пройдут, они будут рассматривать модели с неуправляемыми управляемыми как управляемые. Они не подведут, если кто -то случайно добавит поле к неуправляемой модели. Единственный способ, которым я знаю, чтобы обойти это – создать таблицы вручную.
Это все, что у меня есть на теме. Если бы вы узнали другое решение, я был бы рад узнать об этом.
Оригинал: “https://dev.to/vergeev/testing-against-unmanaged-models-in-django”