Ускорение Джанго Тестирования - PullRequest
16 голосов
/ 26 сентября 2010

Я хочу узнать больше о ваших процессах тестирования с Django.

Справочная информация http://docs.djangoproject.com/en/dev/topics/testing/

Я сталкиваюсь с трудностями при использовании разработки, управляемой тестами.При запуске тестер Django постоянно создает все модели БД в тестовой БД.Для наших текущих проектов (от 40 до 240 моделей) это означает, что для запуска тестов требуется всего 20 секунд.

Это делает его полностью неработоспособным для частого тестирования новой функции.Мой вопрос, как вы, ребята, работаете над этим?

Я пробовал несколько вещей в прошлом a.) - измените загрузчик тестов, чтобы каждый раз использовать один и тот же тестовый db, и применяйте миграции при необходимости b.)- запускать мои модульные тесты из потока __main__ файлов python

опция b неудобна с sys.path, опция a выполнима, но, похоже, не способ django.

Обновление: вариант А действительно не такое уж плохое решение.Это просто немного усилий.Что заставляет меня верить, что люди используют другой обходной путь.Облегчение SQL могло бы быть тем обходным путем.Но я предполагаю, что есть и другие.

Ответы [ 8 ]

9 голосов
/ 27 сентября 2010

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

  1. Я не вижу ничего плохого в написании собственного бегуна тестовэто просто усекает таблицы, а не отбрасывает и создает базу данных.Это джангоизм в том смысле, что он решает конкретную проблему.Открыт билет , позволяющий группировать тестовые наборы в тестовые наборы.После исправления вы сможете группировать тестовые наборы в наборы для более удобного управления.Вы также можете осмотреть патч, прикрепленный к билету, и посмотреть, подойдет ли он вашей цели.

  2. Как подсказал Нед , вы можете использовать базу данных в памяти.Это в значительной степени зависит от вашей модели данных и запросов, переносимых между базами данных.

  3. Если вы еще не пытались реорганизовать свои контрольные примеры.По моему опыту, не все тестовые классы должны подкласс django.test.TestCase.Найдите те тестовые классы, которые можно делать с подклассами unittest.TestCase.Это ускорит процесс немного бит.

  4. Реорганизация приборов.Переместите обычные приборы в один файл и загружайте его до запуска теста, а не внутри каждого класса теста (используя fixtures = [...]).

9 голосов
/ 26 сентября 2010

Использование базы данных SQLite во время тестирования определенно ускоряет процесс.

8 голосов
/ 21 августа 2014

Мне не нравится идея использовать другую базу данных (SQLite) для тестирования, поэтому мои модульные тесты используют ту же базу данных, что и производственное приложение - postgres.

Из коробки это делает создание / уничтожение базы данных самым медленным шагом при выполнении тестов.

Django 1.8 решит эту проблему с флагом - keepdb

Но мы еще не там, поэтому мы должны обойтись другими способами.

Решение 1) Использование pytest-django

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

В моем случае мне нравится использовать PyCharm IDE, и возможность запуска тестов с помощью щелчка правой кнопкой мыши по файлам / методам, безусловно, является плюсом для меня, поэтому мне пришлось пойти на ...

Решение 2) Трюк TEST_MIRROR.

В вашем файле settings.py настройте вашу базу данных следующим образом:

if os.getenv('USE_TEST_DB') == '1':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'mydbtesting',
            'USER': 'mydb',
            'PASSWORD': 'mydb',
            'HOST': 'localhost',
            'PORT': '5432',
            'TEST_MIRROR': 'default',
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'mydb',
            'USER': 'mydb',
            'PASSWORD': 'mydb',
            'HOST': 'localhost',
            'PORT': '5432',
        }
    }

Итак, «mydb» - это база данных, которая будет использоваться для нормального выполнения, а «mydbtesting» - для тестов.

Параметр TEST_MIRROR на самом деле не предназначен для этого, но дело в том, что если вы запускаете тесты с настроенной базой данных, Django не будет заново создавать / уничтожать, что мы и хотим.

Но сначала мы должны создать эту базу данных с чем-то вроде:

export USE_TEST_DB=1
./manage.py syncdb --migrate

Затем, когда вы хотите быстро запустить тесты, просто установите переменную окружения USE_TEST_DB на «1». Чтобы получить те же преимущества в Pycharm, вы можете перейти к Run / Debug Configurations, Defaults / Django тестам, затем к переменным окружения добавьте USE_TEST_DB = 1


UPDATE:

Пример приложения на Github: https://github.com/freedomsponsors/www.freedomsponsors.org/blob/099ec1a7a1c404eba287d4c93d58c8cf600b2769

2 голосов
/ 26 марта 2014

Я нашел другой способ ускорить тестирование. Если ваши тестовые модели являются аутентифицированными пользователями (User модель), и вы установили для них пароль, функция хеширования занимает приличное количество миллисекунд. Что я делаю, так это добавляю это в мои настройки теста:

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.MD5PasswordHasher',
)

Это обеспечивает хеширование MD5 для пароля, которое намного быстрее, чем по умолчанию. В моем случае это улучшенные 12 тестов, каждый из которых создает 7 пользователей, от 4,5 секунд до 500 мс.

Будьте осторожны, не добавляйте это в свои производственные настройки!

2 голосов
/ 26 сентября 2010

Вы можете запустить только те тесты, которые вас интересуют, смотрите здесь: http://docs.djangoproject.com/en/dev/topics/testing/?from=olddocs#running-tests

Как в этом примере - запустите просто конкретный TestCase:

$ ./manage.py test animals.AnimalTest

Что касается тестовой базы данных - она ​​создается и уничтожается при каждом запуске теста :( Также для тестирования вы можете использовать базу данных sqlite, если это возможно в вашем рабочем процессе.

1 голос
/ 29 декабря 2017

Начиная с Django 1.8, вы можете хранить тестовую базу данных, чтобы не перестраивать ее каждый раз при тестировании.Просто добавьте флаг --keepdb.

python manage.py test --keepdb

Если у вас есть новые миграции, исключите флаг --keepdb, и тестовая база данных будет создана с нуля.

1 голос
/ 22 ноября 2013

Я нашел другой способ ускорить тестирование.Самая трудоемкая операция - запись / чтение с жесткого диска (я использую sqlite для тестирования).Решение состоит в том, чтобы создать ramdisk и поместить туда файл базы данных sqlite.Я сократил время тестирования в 10 раз.

Создание виртуального диска:

#!/bin/sh

mkdir -p /tmp/ramdisk; chmod 777 /tmp/ramdisk
mount -t tmpfs -o size=256M tmpfs /tmp/ramdisk/

Изменение пути к файлу БД:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': '/tmp/ramdisk/test.db',
        'TEST_NAME': '/tmp/ramdisk/test.db',
    }
}
0 голосов
/ 02 мая 2012

Вот простые инструменты тестирования, которые предоставляют базу данных без перезагрузки вместе с сигналами, поэтому вам не нужно заботиться о тестовой базе данных https://github.com/plus500s/django-test-tools

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