Кто-то, вероятно, уже разработал технику для освобождения скуки для следующего идиоматического модульного теста:
Шаг 2 является самым утомительным, циклически повторяясь через поля формы. Есть ли какие-либо экономящие время взломы для тестирования форм Django?
[Обновление: я не тестирую обработку форм Django. Я проверяю, что мое приложение производит корректные ответы, когда пользователь вносит изменения в форму. Это - приложение, которое обрабатывает клиническую информацию, следовательно много возможных ответов на тест.]
Это зависит от того, что вы пытаетесь проверить. Я бы нацелился на ваши тесты немного точнее, чем кажется, как вы делаете.
Если код, который вам нужно протестировать, является логикой проверки формы, то я бы просто создал экземпляр класса формы прямо в ваших тестах, передал ему различные словари данных и вызвал .is_valid (), чтобы проверить правильность ошибок или их отсутствие. Нет необходимости задействовать HTML или HTTP-запросы.
Если вы тестируете логику представления (которую следует свести к минимуму), вы, вероятно, захотите использовать тестовый клиент, но вам не нужно проводить многоэтапные тесты или очень много тестов на этом уровне. При тестировании логики представления я бы не очищал HTML (это шаблоны тестирования), я бы использовал response.context, чтобы вытащить объект формы из контекста.
Если вы хотите проверить, что шаблоны содержат правильный HTML-код, чтобы форма действительно работала (чтобы выявлять такие ошибки, как забывание включения формы управления для набора форм в шаблон), я использую WebTest и django-webtest , которые анализируют ваш HTML и упрощают заполнение значений полей и отправку формы, как это сделал бы браузер.
Тщательно подумайте, зачем вам нужно это модульное тестирование. Формы являются частью основной функциональности Django и, как таковые, очень хорошо покрываются собственными модульными тестами Django. Если все, что вы делаете, это базовое создание / обновление, что, по вашему мнению, так и есть, я не вижу причин писать для этого модульные тесты.
Возможно, вы ищете инструменты, которые выполняйте тестирование внешнего интерфейса, например twill или selenium
Оба они генерируют код Python, который может быть включен в тесты django, поэтому, когда вы запускаете тесты, он открывает URL-адреса, отправляет данные и проверяет все, что хотите!
Это должно помочь вам увидеть эти тесты , написанные для селена, для многоразового приложения django с открытым исходным кодом.
Я не понимаю, как и зачем вам нужны модульные тесты для этого. Мне кажется, вы тестируете (и исправляете) возможный ввод пользователя, который очень просто покрывается проверкой формы Django (и проверкой модели в 1.2)
Непонятно, но можно предположить, что у вас есть такие тесты.
class TestSomething( TestCase ):
fixtures = [ "..." ]
def test_field1_should_work( self ):
response= self.client.get( "url with form data already populated" )
form_data = func_to_get_field( response )
form_data['field1']= new value
response= self.client.post( "url", form_data )
self.assert()
def test_field2_should_work( self ):
response= self.client.get( "url with form data already populated" )
form_data = func_to_get_field( response )
form_data['fields']= new value
response= self.client.post( "url", form_data )
self.assert()
Во-первых, вы делаете слишком много. Упрощать.
class TestFormDefaults( TestCase ):
fixtures = [ "some", "known", "database" ]
def test_get_should_provide_defaults( self ):
response= self.client.get( "url with form data already populated" )
self.assert(...)
Вышесказанное доказывает, что формы заполняются значениями по умолчанию.
class TestPost( TestCase ):
fixtures = [ "some", "known", "database" ]
def test_field1_should_work( self ):
# No need to GET URL, TestFormDefaults proved that it workd.
form_data= { expected form content based on fixture and previous test }
form_data['field1']= new value
response= self.client.post( "url", form_data )
self.assert()
Не тратьте время на поиски каждого сообщения. Вы можете отдельно доказать, что операции GET работают. Как только у вас будет это доказательство, просто сделайте POST.
Если ваши POSTS сильно привязаны к сеансу и сохраняют состояние, вы все равно можете выполнить GET, но не парсите ответ. Вы можете доказать (отдельно), что у него есть именно те поля.
Учтите это, чтобы лучше отдыхать.
class TestPost( TestCase ):
fixtures = [ "some", "known", "database" ]
def test_many_changes_should_work( self ):
changes = [
( 'field1', 'someValue', 'some expected response' ),
( 'field2', 'someValue' ),
...
]
for field, value, expected in changes:
self.client.get( "url" ) # doesn't matter what it responds, we've already proven that it works.
form_data= { expected form content based on fixture and previous test }
form_data[field]= value
response self.client.post( "url", form_data )
self.assertEquas( expected, who knows what )
Вышеупомянутое, очевидно, будет работать, но из-за этого количество тестов кажется небольшим.
django-webtest идеально подходит для таких тестов:
from django_webtest import WebTest
class MyTestCase(WebTest):
def test_my_view(self)
form = self.app.get('/my-url/').form
self.assertEqual(form['my_field_10'].value, 'initial value')
form['field_25'] = 'foo'
response = form.submit() # all form fields are submitted
В моем Мнение, что это лучше, чем twill для тестирования django, потому что он обеспечивает доступ к внутренностям django, поэтому родной django response.context
, response.templates
, self.assertTemplateUsed
и self.assertFormError
API поддерживается.
С другой стороны, он лучше собственного тестового клиента django, потому что имеет гораздо более мощный и простой API.
Я немного предвзят;) но я считаю, что django-webtest теперь лучший способ писать тесты django.