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

Как загружать светильники только один раз в модульные тесты django?

В модульных тестах мне нужно загрузить светильники, как показано ниже:

   class TestQuestionBankViews(TestCase):

        # Load fixtures
        fixtures = ['qbank']

        def setUp(self):                           
            login = self.client.login(email="[email protected]",password="welcome")        


        def test_starting_an_exam_view(self):               
            candidate = Candidate.objects.get(email="[email protected]")
            .......etc


        def test_review_view(self):
            self.assertTrue(True)            
            .........

       def test_review_view2(self):
            self.assertTrue(True)
            .........

Проблема:

Эти светильники загружаются для каждого теста, т.е. до test_review_view, test_review_view2 и т.д., поскольку Django сбрасывает базу данных после каждого теста.

Это приводит к тому, что тесты занимают много времени.

Как я могу предотвратить эту избыточную загрузку прибора?

Есть ли способ загрузить светильники в setUp и вымыть их, когда класс тестирования закончен, вместо того, чтобы смывать между каждым тестом?

4b9b3361

Ответ 1

Используя django-nose и немного кода, вы можете делать именно то, что вы просили. С django-носом вы можете иметь функции для каждого пакета, для каждого модуля и для каждого класса. Это позволяет загружать ваши светильники в одну из более высоких функций настройки и отключать перезапуск django.test.TestCase приборов между тестами.

Вот пример тестового файла:

from django.test import TestCase
from django.core import management

    def setup():
        management.call_command('loaddata', 'MyFixture.json', verbosity=0)

    def teardown():
        management.call_command('flush', verbosity=0, interactive=False)

    class MyTestCase(TestCase):

        def _fixture_setup(self):
            pass

        def test_something(self):
            self.assertEqual(1, 1)

Обратите внимание, что установка и отключение находятся за пределами класса. Настройка будет выполняться перед всеми тестовыми классами в этом файле, а отключение будет выполняться после всех тестовых классов.

Внутри класса вы увидите метод def_fixture_setup (self). Это переопределяет функцию, которая сбрасывает базу данных между каждым тестом.

Имейте в виду, что если ваши тесты пишут что-либо в базе данных, это может привести к недействительности ваших тестов. Поэтому любые другие тесты, требующие перезагрузки для каждого теста, должны быть помещены в другой тестовый файл.

Ответ 2

Или используйте setUpModule:

def setUpModule():
    print 'Module setup...'

def tearDownModule():
    print 'Module teardown...'

class Test(unittest.TestCase):
    def setUp(self):
       print 'Class setup...'

    def tearDown(self):
       print 'Class teardown...'

    def test_one(self):
        print 'One'

    def test_two(self):
        print 'Two'

печатает:

Creating test database for alias 'default'...
Module setup...
Class setup...
One
Class teardown...
Class setup...
Two
Class teardown...
Module teardown...

Ответ 3

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

В вашем тестовом файле добавьте эти функции вне любых классов:

from django.core.management import call_command

def setUpModule():
    call_command(
        'loaddata', 
        'path_to_fixture.json',
        verbosity=0
    )

def tearDownModule():
    call_command('flush', interactive=False, verbosity=0)

Если вы не хотите, чтобы эти светильники загружались в базу данных для всех тестовых примеров, разделили тест на несколько файлов, создав новый каталог в приложении tests, добавьте пустой файл __init__.py, чтобы сообщить Python, что это пакет, и добавьте тестовые файлы с именами файлов, начинающимися с test, так как бегун будет искать файлы, соответствующие шаблону test*.py

Ответ 4

Я столкнулся с той же проблемой. В общем, нет действительно хорошего способа сделать это с помощью django test runner. Вы можете быть заинтересованы в этом thread

С учетом сказанного, если все тестовые окна используют один и тот же прибор, и они не изменяют данные каким-либо образом, то использование initial_data будет работать.

Ответ 5

Для того, что стоит, и поскольку нет принятого ответа, Django 1.8 теперь предоставляет эту функциональность из коробки - если вы используете бэкэнд базы данных, поддерживающий транзакции.

Он также добавляет метод TestCase.setUpTestData() для ручного создания тестовых данных один раз для каждого класса TestCase.

См. примечания к выпуску Django 1.8.

Ответ 6

У меня была аналогичная проблема, и я закончил тем, что написал свой собственный тестовый бегун. В моем случае initial_data не было подходящего места для загрузки initial_data во время syncdb, чего я не хотел. Я перепробовал методы setup_ и teardown_test_environment для загрузки моего пользовательского инструментария перед запуском набора тестов и его удаления после его завершения.

Ответ 7

django-nose предоставляет готовое решение этой проблемы: просто подкласс django_nose.FastFixtureTestCase.

Кроме того, django-nose поддерживает привязку приборов, что может ускорить ваш тест, даже больше, загружая каждый уникальный набор светильников один раз за испытательный прогон. После подкласса FastFixtureTestCase, где это необходимо, запустите тестовый бегун django-нос, используя опцию --with-fixture-bundling.

Подробнее см. django-нос на pypi.