Как загружать светильники только один раз в модульные тесты 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
и вымыть их, когда класс тестирования закончен, вместо того, чтобы смывать между каждым тестом?
Ответы
Ответ 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.