Выполнение и написание тестов¶
Хороший код нуждается в тестах.
Такой проект, как django CMS, просто не может позволить себе включать новый код, который не сопровождается собственными тестами.
Тесты обеспечивают некоторый необходимый минимум уверенности: они могут показать, что код будет вести себя так, как ожидается, и помочь определить, что идет не так, если что-то нарушается.
Не настаивать на хороших тестах при написании кода - это все равно, что позволить банде подростков без водительских прав взять вашу машину в пятницу вечером, даже если вы считаете их очень милыми подростками и они действительно обещают быть осторожными.
Нам, конечно, нужны ваши вклады и исправления, но нам нужны и ваши тесты с ними. В противном случае мы поставим под угрозу нашу кодовую базу.
Поэтому вам придется включать тесты, если вы хотите внести свой вклад. Однако написание тестов не представляет особой сложности, и в коде есть множество примеров, которые помогут вам.
Выполнение тестов¶
Существует несколько способов сделать это, но вот один из них, который поможет вам начать:
# create a virtual environment
virtualenv test-django-cms
# activate it
cd test-django-cms/
source bin/activate
# get django CMS from GitHub
git clone https://github.com/django-cms/django-cms.git
# install the dependencies for testing
# note that requirements files for other Django versions are also provided
pip install -r django-cms/test_requirements/django-X.Y.txt
# run the test suite
# note that you must be in the django-cms directory when you do this,
# otherwise you'll get "Template not found" errors
cd django-cms
python manage.py test
Запуск может занять несколько минут.
Когда вы запускаете тесты против своего нового кода, не забывайте, что полезно повторить их для разных версий Python и Django.
Проблемы с выполнением тестов¶
Мы работаем над улучшением производительности и надежности нашего набора тестов. Мы знаем о некоторых проблемах, но нам нужна обратная связь от людей, использующих широкий спектр систем и конфигураций, чтобы извлечь пользу из их опыта.
Пожалуйста, сообщайте о любых проблемах на нашем сайте GitHub repository.
Если вы можете помочь улучшить набор тестов, ваш вклад будет особенно ценен.
Пользователи OS X¶
В некоторых версиях OS X необходимо установить gettext
, чтобы он был доступен для Django. Если вы запустите тесты и обнаружите, что различные тесты в cms.tests.frontend
вызывают ошибки, то, скорее всего, у вас эта проблема.
Решение заключается в следующем:
brew install gettext && brew link --force gettext
(Для этого необходимо установить Homebrew)
ERROR: test_copy_to_from_clipboard (cms.tests.frontend.PlaceholderBasicTests)
¶
Вы можете обнаружить, что один фронтенд-тест вызывает ошибку. Для некоторых пользователей это иногда происходит при запуске всего набора. Чтобы обойти это, вы можете вызывать класс теста самостоятельно:
manage.py test cms.PlaceholderBasicTests
после чего он должен запуститься без ошибок.
ERROR: zlib is required unless explicitly disabled using --disable-zlib, aborting
¶
Если вы столкнулись с этой проблемой, убедитесь, что установили zlib с помощью Homebrew:
brew install libjpeg zlib && brew link --force zlib
Расширенные опции тестирования¶
Выполните manage.py test --help
для получения полного списка дополнительных опций.
Используйте --parallel
, чтобы распределить тестовые случаи по ядрам процессора.
Используйте --failed
, чтобы запустить только те тесты, которые не прошли во время последнего запуска.
Используйте --retest
, чтобы запустить тесты, используя ту же конфигурацию, что и при последнем запуске.
Используйте --vanilla
, чтобы обойти систему расширенного тестирования и использовать встроенную команду Django test.
Чтобы использовать другую базу данных, установите переменную окружения DATABASE_URL
в значение, совместимое с dj-database-url.
Выполнение фронтенд-тестов¶
У нас есть два типа фронтенд-тестов: модульные тесты и интеграционные тесты. Для модульных тестов мы используем Karma в качестве программы запуска тестов и Jasmine в качестве фреймворка для тестов.
Интеграционные тесты выполняются на PhantomJS и собираются с помощью CasperJS.
Для того чтобы их можно было запустить, необходимо установить необходимые зависимости, как указано в frontend tooling installation instructions.
Линтинг запускается и для тестовых файлов при gulp tests:lint
. Для того чтобы запустить линтинг непрерывно, сделайте:
gulp watch
Модульные тесты¶
Юнит-тесты можно запускать следующим образом:
gulp tests:unit
Если ваш код не работает и вы хотите запустить только определенные файлы, вы можете указать параметр --tests
с именами файлов, разделенными запятыми, например, так:
gulp tests:unit --tests=cms.base,cms.modal
Если вы хотите запускать тесты непрерывно, вы можете использовать команду watch:
gulp tests:unit:watch
Это позволит повторно запускать набор тестов при каждом изменении исходного или тестового файла. По умолчанию тесты запускаются на PhantomJS, но при запуске Karma в режиме watch вы также можете посетить сервер, который он порождает, с помощью настоящего браузера.
INFO [karma]: Сервер Karma v0.13.15 запущен по адресу http://localhost:9876/.
В Travis CI мы используем интеграцию SauceLabs для запуска тестов в различных реальных браузерах, но вы можете отказаться от их запуска на saucelabs, используя маркер [skip saucelabs]
в сообщении коммита, аналогично тому, как вы полностью пропустите сборку, используя [skip ci]
.
Мы используем Jasmine в качестве фреймворка для тестирования и Istanbul в качестве инструмента для покрытия кода.
Интеграционные тесты¶
Для того чтобы запустить интеграционные тесты, вам необходимо установить как минимум версию django CMS из текущей директории и django-app-helper в ваш virtualenv. Все команды должны выполняться из корня репозитория. Если у вас еще нет virtualenv, сначала создайте и активируйте его:
virtualenv env
. env/bin/activate
Затем установите минимально необходимые зависимости:
pip install -r test_requirements/django-1.8.txt
pip install -e .
Теперь вы сможете запускать тесты с помощью этой команды:
gulp tests:integration
Команда запустит сервер, подождет минуту для выполнения миграций и запустит интеграционные тесты на нем. В качестве базы данных будет использоваться testdb.sqlite
. Если вы хотите начать с чистого состояния, вы можете использовать аргумент --clean
.
Некоторые тесты требуют различной конфигурации сервера, поэтому возможно, что сервер остановится, а другой вариант запустится с другими аргументами. Загляните в testserver.py, если вам нужно настроить параметры тестового сервера.
Во время отладки вы можете использовать параметр --tests
, чтобы запускать тестовые наборы отдельно.:
gulp tests:integration --tests=pagetree
gulp tests:integration --tests=loginAdmin,toolbar
Если указанные тесты требуют разных серверов, они будут сгруппированы для ускорения работы, поэтому порядок может не совпадать с тем, который вы указали в аргументе.
При локальном запуске иногда полезно визуализировать результаты тестов. Для этого вы можете установить casperjs visual debugging utility, и запускать тесты с дополнительным аргументом --visual
. Он попытается связаться с сервером и отобразит ход выполнения теста, который затем можно перемотать.
Иногда бывает полезно не перезапускать сервер при создании тестов, для этого можно выполнить python testserver.py
с необходимыми аргументами в одной оболочке и gulp tests:integration --no-server
в другой. Однако вам придется самостоятельно очищать состояние, если написанный вами тест не сработает.
Написание тестов¶
Внесение тестов считается очень престижным вкладом (этим вы значительно облегчаете будущую работу всех пользователей). Мы всегда примем вклад в виде теста без кода, но не кода без теста - это должно дать вам представление о том, насколько важны тесты.
Что нам нужно¶
У нас есть обширная и полная библиотека юнит-тестов и интеграционных тестов с хорошим покрытием.
Как правило, тесты должны быть:
Унитарные (насколько это возможно). т.е. должны тестировать по возможности только одну функцию/метод/класс. Это само определение юнит-тестов. Интеграционные тесты тоже интересны, но требуют больше времени на поддержку, так как имеют большую вероятность поломки.
Короткое выполнение. Здесь нет жестких цифр, но если один ваш тест удваивает время, которое требуется всем для его выполнения, это, вероятно, указывает на то, что вы делаете это неправильно.
Простота понимания. Если ваш тестовый код не очевиден, добавьте комментарии о том, что он делает.