Django: Как создать модель динамично только для тестирования

Я думаю, вы не должны сами это кодировать, но посмотрите на Tree :: Visualize , который, кажется, является хорошей реализацией Perl с различными возможными стилями и использует / порт один из алгоритмов там .

62
задан muhuk 2 February 2009 в 11:35
поделиться

3 ответа

Можно поместить тесты в tests/ подкаталог приложения (а не tests.py файл) и включать tests/models.py с моделями только для теста.

Затем предоставляют выполняющий тест сценарий ( пример ), который включает Ваш tests/ "приложение" в INSTALLED_APPS. (Это не работает, когда запущенное приложение тестирует из реального проекта, который не будет иметь тестового приложения в INSTALLED_APPS, но я редко нахожу полезным запустить допускающие повторное использование тесты приложения из проекта, и Django 1.6 + не делает по умолчанию.)

( ПРИМЕЧАНИЕ : альтернативный динамический метод описал только ниже работ в Django 1.1 +, если Ваш тестовый сценарий разделяет на подклассы TransactionTestCase - который значительно замедляет Ваши тесты - и больше не работает вообще в Django 1.7 +. Это оставляют здесь только для исторического интереса; не используйте его.)

В начале Ваших тестов (т.е. в методе установки, или в начале ряда doctests), можно динамично добавить "myapp.tests" к установке INSTALLED_APPS и затем сделать это:

from django.core.management import call_command
from django.db.models import loading
loading.cache.loaded = False
call_command('syncdb', verbosity=0)

Затем в конце Ваших тестов, необходимо вымыться путем восстановления старой версии INSTALLED_APPS и очистки кэша приложения снова.

Этот класс инкапсулирует шаблон, таким образом, он не загромождает Ваш тестовый код вполне так же.

51
ответ дан Carl Meyer 7 November 2019 в 13:07
поделиться

Это решение работает только для более ранних версий django (до 1.7 ). Вы можете легко проверить свою версию:

import django
django.VERSION < (1, 7)

Исходный ответ:

Это довольно странно, но form me работает очень простой шаблон:

  1. добавьте tests.py в приложение, которое вы собираетесь протестировать,
  2. в этом файле просто определите модели тестирования,
  3. ниже поместите свой тестовый код (определение doctest или TestCase),

Ниже я поместил код, который определяет модель статьи, которая необходима только для тестов (она существует в someapp / tests.py и я можно проверить это просто с помощью: ./ manage.py test someapp ):

class Article(models.Model):
    title = models.CharField(max_length=128)
    description = models.TextField()
    document = DocumentTextField(template=lambda i: i.description)

    def __unicode__(self):
        return self.title

__test__ = {"doctest": """
#smuggling model for tests
>>> from .tests import Article

#testing data
>>> by_two = Article.objects.create(title="divisible by two", description="two four six eight")
>>> by_three = Article.objects.create(title="divisible by three", description="three six nine")
>>> by_four = Article.objects.create(title="divisible by four", description="four four eight")

>>> Article.objects.all().search(document='four')
[<Article: divisible by two>, <Article: divisible by four>]
>>> Article.objects.all().search(document='three')
[<Article: divisible by three>]
"""}

Модульные тесты также работают с таким определением модели.

11
ответ дан 24 November 2019 в 16:44
поделиться

Ответ @ paluh требует добавления нежелательного кода в не тестовый файл, и, по моему опыту, решение @ carl не работает с django.test.TestCase, который является нужно было использовать приспособления. Если вы хотите использовать django.test.TestCase, вам необходимо убедиться, что вы вызываете syncdb до загрузки фикстур. Это требует переопределения метода _pre_setup (помещения кода в метод setUp недостаточно). Я использую свою версию TestCase, которая позволяет мне добавлять приложения с тестовыми моделями. Он определяется следующим образом:

from django.conf import settings
from django.core.management import call_command
from django.db.models import loading
from django import test

class TestCase(test.TestCase):
    apps = ()

    def _pre_setup(self):
        # Add the models to the db.
        self._original_installed_apps = list(settings.INSTALLED_APPS)
        for app in self.apps:
            settings.INSTALLED_APPS.append(app)
        loading.cache.loaded = False
        call_command('syncdb', interactive=False, verbosity=0)
        # Call the original method that does the fixtures etc.
        super(TestCase, self)._pre_setup()

    def _post_teardown(self):
        # Call the original method.
        super(TestCase, self)._post_teardown()
        # Restore the settings.
        settings.INSTALLED_APPS = self._original_installed_apps
        loading.cache.loaded = False
18
ответ дан 24 November 2019 в 16:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: