Как запустить модульные тесты django в производственной базе данных?

Я начинаю разработку TDD и пишу модульные тесты для своего приложения django. Я знаю о приспособлениях и знаю, как должны выполняться тесты, но для данного теста мне действительно нужно выполнить его для всей базы данных, а приспособление json для базы данных с 10+ миллионами строк - это не то, что я хотел бы обрабатывать , кроме того, этот тест предназначен только для чтения.

Итак, вопрос в том, как вы настраиваете свои тестовые наборы для работы в производственной базе данных? Я предполагаю, что это может быть так же просто, как добавить параметр DATABASE_NAME в метод setUp определенного теста. Но settings.DATABASE_NAME = "prod_db" приводит к ошибке "NameError: глобальное имя 'settings' не определено" во время выполнения теста. Более того, существует риск, описанный в http://code.djangoproject.com/ticket/11987 , что вы можете случайно удалить производственную базу данных.

Итак, как можно или, что еще лучше, как лучше всего запустить один тест набора тестов в производственной базе данных вместо временной?

Заранее приветствую любые мнения!


person James    schedule 29.10.2009    source источник


Ответы (5)


Во-первых, если вы запускаете его в производственной базе данных, это не очень похоже на «модульный» тест.

Это первоклассное пакетное задание, и к нему следует относиться как к первоклассному производственному пакетному заданию.

Вы не можете использовать команду Django test для просмотра производственных данных. Он всегда создает пустую базу данных, которая заполняется из фикстур в TestCase.

Вы можете сделать обработку своей производственной базы данных правильной команда управления. В нем вся среда настроена должным образом, так что ваша команда может просто использовать Django ORM для обработки ваших данных.

Альтернативный вариант - убедиться, что вы настроили свои настройки. Либо используйте переменную среды DJANGO_SETTINGS_MODULE, либо функцию settings.configure() для создания среды.

Затем вы можете импортировать модели и выполнить необходимую обработку в производственной базе данных.

Вы можете назвать это «тестом», если хотите, но вы смотрите на производственные данные, поэтому с ним нужно обращаться как с производственным приложением в отношении получения файла настроек и использования правильной конфигурации ORM.

person S.Lott    schedule 29.10.2009
comment
Спасибо за отличный ответ! Я согласен, что это не лучшая практика, которой я пытаюсь достичь. Написание правильной управленческой команды звучит как правильный способ справиться с ситуациями как таковыми. Спасибо за направление! Думаю, я так и сделаю, но, чтобы выяснить, что такое возможно, не могли бы вы указать, как правильно использовать settings.configure () в моем случае? помещая из django.conf параметры импорта и settings.configure (DATABASE_NAME = prod_db) в результаты модульного теста в уже настроенную ошибку времени выполнения (и это именно то, что говорят документы)? - person James; 30.10.2009
comment
Несмотря на то, что в документации говорится, что изменение настроек во время выполнения не должно выполняться, я думаю, что таким образом эта проблема может быть решена. Кстати, Стивен, я проверил ваш веб-сайт, и Python для программистов и объектно-ориентированный дизайн для программистов стали одними из лучших книг в моем списке tor-ead-next. Большое спасибо за то, что написали и поделились ими! - person James; 30.10.2009
comment
Вы не можете изменить настройки Django во время выполнения. Вы можете указать настройки через файл или с помощью метода .configure(). Выбери один. Динамических настроек не существует. - person S.Lott; 30.10.2009
comment
Я не могу понять, почему вы попробовали и DJANGO_SETTINGS_MODULE, и settings.confgure(). Просто выберите один. У вас может быть несколько файлов настроек (с разными именами). Вы можете использовать один settings файл для модульного теста И для этих сканирований производственной базы данных. - person S.Lott; 30.10.2009
comment
Если то, что описывает @James, является тестом BDD, он же функциональный тест или интеграционный тест, что, вероятно, лучше всего сделать с помощью таких инструментов, как behavior, тогда может иметь смысл запустить его с (копией) производственной базы данных. Только мои два цента на обсуждение ... - person Peterino; 27.05.2015
comment
@Peterino Когда я начал свои тесты, которые привели меня к этому вопросу, я знал, что это интеграционные тесты, но я не знал behave. Спасибо за изучение нового инструмента. (Я бы с удовольствием реализовал свои тесты с помощью функции behavior, но из-за нехватки времени им придется пока оставаться командой управления django.) - person hlongmore; 21.02.2018
comment
@hlongmore Поскольку вы используете Django, вы можете взглянуть на behave-django, github.com/behave/ поведение-django. Он имеет встроенную поддержку для запуска тестов с (копиями) существующих баз данных. - person Peterino; 21.02.2018

На случай, если кто-то погулит здесь в поисках решения данной проблемы, вот скелет того, как выполнять модульные тесты в производственной базе данных django. Проверьте раздел django docs здесь, чтобы узнать о структуре файлов / каталогов и инструкциях по размещению данного кода. Он должен находиться в yourapp/management/commands/newcommandname.py, а папки управления и команд должны содержать пустые __init__.py файлы, что заставляет python рассматривать их как допустимые модули.

Набор тестов может запускаться как:

$ python manage.py newcommandname

А вот и код, который нужно вставить yourapp/management/commands/newcommandname.py:

from django.core.management.base import BaseCommand
import unittest

class Command(BaseCommand):
    help = """
    If you need Arguments, please check other modules in 
    django/core/management/commands.
    """

    def handle(self, **options):
        suite = unittest.TestLoader().loadTestsFromTestCase(TestChronology)
        unittest.TextTestRunner().run(suite)


class TestChronology(unittest.TestCase):
    def setUp(self):
        print "Write your pre-test prerequisites here"

    def test_equality(self):
        """
        Tests that 1 + 1 always equals 2.
        """
        from core.models import Yourmodel
        self.failUnlessEqual(1 + 1, 2)
person James    schedule 30.10.2009
comment
Спасибо! Этот ответ принадлежит к топу :) - person Danilo Bargen; 29.04.2011
comment
+1 за ответ на вопрос и за демонстрацию того, как это сделать, создав новую команду управления. - person MrOodles; 21.08.2012
comment
NoArgsCommand устарел и будет удален в Django 1.10 - теперь лучше всего использовать BaseCommand, по умолчанию для которого нет аргументов. Все, что вам нужно изменить из приведенного выше ответа: from django.core.management.base import BaseCommand ... class Command(BaseCommand) ... def handle(self, **options). - person Chris; 28.12.2015

Этот TEST_RUNNER работает на Django 1.3.

from django.test.simple import DjangoTestSuiteRunner as TestRunner

class DjangoTestSuiteRunner(TestRunner):
    def setup_databases(self, **kwargs):
        pass

    def teardown_databases(self, old_config, **kwargs):
        pass
person Noel Pure    schedule 06.06.2014
comment
Для Django 1.8 создайте подкласс класса DiscoverRunner (from django.test.runner import DiscoverRunner). - person dhobbs; 18.11.2015

Юнит-тест предназначен для тестирования без каких-либо побочных эффектов. Хотя в вашем тесте не будет ничего, что известно как unittest. Если вы все равно хотите это сделать, вы можете использовать настраиваемую программу запуска тестов, которая настраивает базу данных (или, в вашем случае, используя существующую базу данных).

Вы можете установить параметр TEST_RUNNER в файле settings.py. По умолчанию находится в django.test.simple.run_tests. Вы можете посмотреть исходный код здесь: http://code.djangoproject.com/browser/django/trunk/django/test/simple.py

Скопируйте и вставьте код в новый файл и удалите из кода следующие строки:

connection.creation.create_test_db(verbosity, autoclobber=not interactive)
...
connection.creation.destroy_test_db(old_name, verbosity)

Это предотвратит создание django тестовой базы данных и сброс конфигурации базы данных вашего файла настроек.

person Gregor Müllegger    schedule 30.10.2009
comment
Вроде не работает: тестирование Djanfo не может найти рабочую базу данных :-( - person luc; 20.11.2009

Не очень хорошая идея, но если вы знаете, что делаете (в основном ломаете производство), вы можете проверить этот параметр:

https://docs.djangoproject.com/en/2.2/ref/settings/#test

DATABASES = {
  'default': {
     ...
     'TEST': {
        'NAME': 'your prod db'
     }
}
person Michel Samia    schedule 13.08.2019