Джанго: Как создать модель динамически только для тестирования - PullRequest
58 голосов
/ 02 февраля 2009

У меня есть приложение Django, для которого требуется атрибут settings в виде:

RELATED_MODELS = ('appname1.modelname1.attribute1',
                  'appname1.modelname2.attribute2', 
                  'appname2.modelname3.attribute3', ...)

Затем перехватывает их сигнал post_save для обновления какой-либо другой фиксированной модели в зависимости от attributeN.

Я хотел бы проверить это поведение, и тесты должны работать, даже если это приложение является единственным в проекте (за исключением его собственных зависимостей, никакое другое приложение-оболочка устанавливать не нужно). Как я могу создать и прикрепить / зарегистрировать / активировать макеты только для тестовой базы данных? (или это вообще возможно?)

Решения, которые позволяют мне использовать тестовые приборы, были бы великолепны.

Ответы [ 11 ]

0 голосов
/ 28 декабря 2018

Кто-то уже упоминал Билет Django # 7835 , но, похоже, есть более поздний ответ, который выглядит гораздо более многообещающим для более свежих версий Django. В частности, # 42 , который предлагает другой TestRunner:

from importlib.util import find_spec
import unittest

from django.apps import apps
from django.conf import settings
from django.test.runner import DiscoverRunner


class TestLoader(unittest.TestLoader):
    """ Loader that reports all successful loads to a runner """
    def __init__(self, *args, runner, **kwargs):
        self.runner = runner
        super().__init__(*args, **kwargs)

    def loadTestsFromModule(self, module, pattern=None):
        suite = super().loadTestsFromModule(module, pattern)
        if suite.countTestCases():
            self.runner.register_test_module(module)
        return suite


class RunnerWithTestModels(DiscoverRunner):
    """ Test Runner that will add any test packages with a 'models' module to INSTALLED_APPS.
        Allows test only models to be defined within any package that contains tests.
        All test models should be set with app_label = 'tests'
    """
    def __init__(self, *args, **kwargs):
        self.test_packages = set()
        self.test_loader = TestLoader(runner=self)
        super().__init__(*args, **kwargs)

    def register_test_module(self, module):
        self.test_packages.add(module.__package__)

    def setup_databases(self, **kwargs):
        # Look for test models
        test_apps = set()
        for package in self.test_packages:
            if find_spec('.models', package):
                test_apps.add(package)
        # Add test apps with models to INSTALLED_APPS that aren't already there
        new_installed = settings.INSTALLED_APPS + tuple(ta for ta in test_apps if ta not in settings.INSTALLED_APPS)
        apps.set_installed_apps(new_installed)
        return super().setup_databases(**kwargs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...