Как загрузить приборы только один раз в модульных тестах Django? - PullRequest
24 голосов
/ 11 июня 2009

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

   class TestQuestionBankViews(TestCase):

        # Load fixtures
        fixtures = ['qbank']

        def setUp(self):                           
            login = self.client.login(email="mail@gmail.com",password="welcome")        


        def test_starting_an_exam_view(self):               
            candidate = Candidate.objects.get(email="mail@gmail.com")
            .......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 и сбрасывать их по окончании класса теста, а не промывать между каждым тестом?

Ответы [ 7 ]

19 голосов
/ 22 марта 2012

Используя django-nose и немного кода, вы можете сделать именно то, что вы просили. С django-nose вы можете иметь функции установки и удаления для каждого пакета, для каждого модуля и для каждого класса. Это позволяет вам загружать ваши приборы в одну из высших функций настройки и отключать сброс приборов 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) . Это переопределяет функцию, которая сбрасывает базу данных между каждым тестом.

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

13 голосов
/ 26 сентября 2013

Или используйте 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...
6 голосов
/ 18 июля 2014

Если вы не хотите устанавливать новый пакет только для этой цели, вы можете объединить решение Тома Уэйнрайта и решение 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

5 голосов
/ 28 октября 2015

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

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

См. заметки о выпуске Django 1.8 .

3 голосов
/ 11 июня 2009

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

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

1 голос
/ 19 августа 2009

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

0 голосов
/ 21 марта 2014

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

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

См. Джанго-нос на pypi для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...