2009-11-01 1 views
4

Я использую устройство единичного тестирования Django (manage.py test), которое выдает ошибку и останавливается, когда код генерирует предупреждение. Этот же код при тестировании со стандартным модулем unittest Python генерирует предупреждения, но продолжает выполнение кода через них.Испытывает ли Django Unit Test предупреждения на исключения?

Небольшое исследование показывает, что Python может быть настроен на то, чтобы поднять предупреждения к исключениям, которые, я полагаю, заставили бы среду тестирования думать, что произошла ошибка. К сожалению, документация Django по тестированию немного освещена в определении «ошибки» или как изменить обработку предупреждений.

So: Является ли модулем тестирования модуля Django тестирование предупреждений об ошибках по умолчанию? Есть ли какое-то средство в Django для изменения этого поведения? Если нет, есть ли какие-либо предложения о том, как я могу Django распечатывать ошибки, но продолжать выполнение кода? Или я полностью неправильно определил проблему?

UPDATE: Тестовый код останавливается на предупреждениях, вызванных вызовами MySQLdb. Эти вызовы выполняются модулем, который выдает те же предупреждения при тестировании в рамках платформы Unitest Python, но не останавливается. Я подумаю об эффективном способе репликации ситуации в коде, достаточно кратком для публикации.

ОТВЕТ:

Немного больше исследований показывает, что это поведение связано с MySQL бэкэнда Джанго:

/usr/...django/.../mysql/base.py:

if settings.DEBUG: 
    ... 
    filterwarnings("error", category=Database.Warning) 

Когда я меняю settings.py так, что DEBUG = False, код выдает предупреждение, но не останавливается.

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

+0

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

+0

Из документации, проверка Django не запускает режим DEBUG: http://docs.djangoproject.com/en/dev/topics/testing/#other-test-conditions, поэтому я не уверен, что код, на который вы ссылались вызывает предупреждения/ошибки. Как вы запускаете «таблицу не существует» SQL как часть тестового процесса ./manage.py? – michaeljoseph

ответ

2

Учитывая обновленную информацию, я склонен сказать, что это правильно для Django; Предупреждения MySQL могут указывать на любое количество вещей вплоть до потери данных (например, MySQL будет предупреждать и молча усекать, если вы попытаетесь вставить значение, большее, чем может содержать столбец), и это то, что вы хотели бы узнайте о тестировании. Поэтому, вероятно, лучше всего посмотреть на предупреждения, которые он генерирует, и изменить свой код, чтобы он больше не вызывал эти предупреждения.

+0

Поведение кажется мне разумным, но не считайте себя достаточно экспертом, чтобы сказать. Предупреждение, которое я получаю, это «таблица не существует» в качестве ответа на «drop table if exists» - я не знаю, как писать SQL, чтобы избежать этого. Надеюсь, мои заметки обсудят ситуацию как поведение, которое не соответствует моей конкретной ситуации, а не ошибке. – chernevik

+0

Хотя MySQL будет предупреждать об усечении и продолжить вставку, они считают это нормально по умолчанию.Я лично считаю, что Django должен отнестись к поставщику БД в этих случаях. Если Django считает, что он должен эскалировать предупреждение (усеченные данные) на ошибку (данные оказываются неблагоприятным образом), он должен либо установить SQLMODE на традиционный, сказать пользователю, что MySQL не находится в традиционном режиме во время запуска, либо просто отметьте вопрос в документах. http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_traditional –

+0

Адам, Django имеет свои независимые от БД стандарты для того, что есть и не является правильным поведением (например, мы также переходим к некоторым длинам, чтобы обеспечить ссылочную целостность независимо от того, работает ли механизм хранения MySQL). И, действительно, это правильная вещь, независимо от того, чувствует ли поставщик БД, что потери/искажения данных приемлемы. –