Подтвердить что ты не робот

Модели внутри тестов - выпуск Django 1.7

Я пытаюсь перенести мой проект на использование Django 1.7. Все в порядке, кроме 1 вещи. Модели внутри папок тестов.

Django 1.7 новые миграции запускают команду миграции внутри. Перед запуском syncdb. Это означает, что если модель не включена в миграцию - она ​​не будет заполнена БД (а также проверять БД). Это то, что я сейчас испытываю.

Что я делаю:

В моем /app/tests/models.py у меня есть фиктивная модель: class TestBaseImage(BaseImage): pass Все, что он делает, это наследовать от абстрактной модели BaseImage.

Затем в тестах я создаю экземпляры этой фиктивной модели для ее проверки.

Проблема в том, что она больше не работает. Он не включен в миграцию (это очевидно, поскольку я не хочу сохранять свои тестовые модели в производственной БД). Выполнение моих тестов вызывает ошибку DB, говорящей, что table does not exist. Это имеет смысл, поскольку оно не включено в миграцию.

Есть ли способ заставить его работать с новой системой миграции? Я не могу найти способ "исправить" это.

Код, который я использую:

приложение/тесты/models.py

from ..models import BaseImage


class TestBaseImage(BaseImage):
    """Dummy model just to test BaseImage abstract class"""
    pass

приложение /models.py

class BaseImage(models.Model):
    # ... fields ...
    class Meta:
        abstract = True

заводы:

class BaseImageFactory(factory.django.DjangoModelFactory):
    """Factory class for Vessel model"""
    FACTORY_FOR = BaseImage
    ABSTRACT_FACTORY = True


class PortImageFactory(BaseImageFactory):
    FACTORY_FOR = PortImage

пример теста:

def get_model_field(model, field_name):
    """Returns field instance"""
    return model._meta.get_field_by_name(field_name)[0]


def test_owner_field(self):
    """Tests owner field"""
    field = get_model_field(BaseImage, "owner")

    self.assertIsInstance(field, models.ForeignKey)
    self.assertEqual(field.rel.to, get_user_model())
4b9b3361

Ответ 1

Существует билет, запрашивающий способ сделать только тестовые модели здесь

В качестве обходного пути вы можете отделить ваши tests.py и сделать его приложением.

tests
|--migrations
|--__init__.py
|--models.py
|--tests.py

В итоге вы получите что-то вроде этого:

myapp
|-migrations
|-tests
|--migrations
|--__init__.py
|--models.py
|--tests.py
|-__init__.py
|-models.py
|-views.py

Затем вы должны добавить его в свой INSTALLED_APPS

INSTALLED_APPS = (
    # ...
    'myapp',
    'myapp.tests',
)

Вероятно, вы не хотите устанавливать myapp.tests на производство, поэтому вы можете хранить отдельные файлы настроек. Что-то вроде этого:

INSTALLED_APPS = (
    # ...
    'myapp',
)

try:
    from local_settings import *
except ImportError:
    pass

Или еще лучше, создайте тестовый бегун и установите там свои тесты.

И последнее, но не менее важное: не забудьте запустить python manage.py makemigrations

Ответ 2

Вот обходной путь, который, похоже, работает. Обманите структуру миграции, считая, что для вашего приложения нет миграции. В settings.py:

if 'test' in sys.argv:
    # Only during unittests...

    # myapp uses a test-only model, which won't be loaded if we only load
    # our real migration files, so point to a nonexistent one, which will make
    # the test runner fall back to 'syncdb' behavior.
    MIGRATION_MODULES = {
        'myapp': 'myapp.migrations_not_used_in_tests'
    }

Я нашел идею на первом сообщении в потоке рассылки Django dev, а также в настоящее время используется в Django, но он может не работать в будущих версиях Django, где требуются миграции, и удаляется "syncdb fallback".