Как вы тестируете наборы форм в Django?

Итак, мне нужно протестировать представление, более точную форму представления. Поэтому я создаю такой модульный тест.

class ViewTest(TestCase):
    fixtures = ['fixture.json']
    def setUp(self):
        self.client = Client()
    def test_company_create(self):
        post_data = {
            'form-0-user': '',
            'form-0-share': '',
            'form-TOTAL_FORMS': 1,
            'form-INITIAL_FORMS': 0,
            'form-MAX_NUM_FORMS': 10
        }
    resp = self.client.post('/company/create/', post_data)
    self.assertFormError (resp, 'shareholder_formset', 'share', 'This field is required.')
    self.assertFormError (resp, 'shareholder_formset', 'user', 'This field is required.')

Конечно, я возвращаю ошибку

AttributeError: объект «ShareholderFormFormSet» не имеет атрибута «поля»

Потому что в наборе форм есть формы, а не поля... Так как же правильно протестировать набор форм?


person Viktor    schedule 14.05.2013    source источник
comment
Взгляните на аналогичный вопрос: stackoverflow.com/questions/1630754/ django-formset-unit-test.   -  person alecxe    schedule 14.05.2013
comment
@alecxe Этот вопрос похож только в том смысле, что он также касается наборов форм и модульного тестирования ... @Viktor А как насчет простого тестирования ShareholderForm? Похоже, это то, что вы пытаетесь сделать со своими утверждениями в любом случае...   -  person Ngenator    schedule 14.05.2013
comment
Вы оба тестируете представление и форму в этом модульном тесте. Нет необходимости выполнять POST для проверки формы. См. раздел «Формы тестирования» в Руководстве по Тестирование в Django #2   -  person gertvdijk    schedule 14.05.2013
comment
@gertvdijk Проблема в том, что у меня есть форма и набор форм в одном представлении. И в основном, когда данные формы и другие данные формы проходят проверку по умолчанию, в представлении я сравниваю данные из этих форм, и если они не совпадают, то я вручную в представлении поднимаю ошибку. Я так делаю только потому, что нет другого способа сравнить данные из разных форм, в моем случае форма и i formset... Так что да, если не сравнивать данные из разных форм, и нет необходимости тестировать форму в представлении, в моем случае это так не работает.   -  person Viktor    schedule 14.05.2013
comment
@alecxe Это совершенно два разных вопроса.   -  person Viktor    schedule 14.05.2013
comment
@Viktor Я комментирую, а не отвечаю. ;)   -  person gertvdijk    schedule 14.05.2013
comment
@ Виктор, конечно, поэтому это комментарий. Извиняюсь.   -  person alecxe    schedule 14.05.2013
comment
@Ngenator Это не сработает, потому что ошибка, которую я пытаюсь проверить, возникает в представлении, когда я сравниваю форму и набор форм, и если они не совпадают, я вызываю ValidationError...   -  person Viktor    schedule 14.05.2013
comment
Ну :) это просто грустно...   -  person Viktor    schedule 14.05.2013
comment
Ну, как вариант, вы можете использовать подход более высокого уровня и протестировать свой вид и набор форм с помощью веб-теста, механизации или селена.   -  person alecxe    schedule 14.05.2013
comment
@alecxe да, это правда. Просто надеялся, что есть простой способ сделать это через django :))). В любом случае, спасибо.   -  person Viktor    schedule 14.05.2013
comment
@Viktor Ошибка обычно возникает из-за формы, а не из-за представления. Они просто отображают ошибку, если вы существенно не изменили ситуацию...   -  person Ngenator    schedule 14.05.2013
comment
@Ngenator Обычно. Но если вам нужно проверить данные между двумя разными формами. Тогда как ты поступишь? Хочу услышать вашу версию. Единственный способ, который я нашел, - это две проверки в представлении. Может быть, вы можете предложить что-то лучше.   -  person Viktor    schedule 15.05.2013
comment
Таким образом, данные из каждой формы зависят от данных из другой, и вы сравниваете эти данные в представлении? Я исходил из предположения, что каждая форма независима от другой. В противном случае вы больше не тестируете набор форм, вы действительно тестируете свое представление...   -  person Ngenator    schedule 15.05.2013
comment
Я только что разместил здесь ответ, который может помочь воссоздать информацию о данных публикации: stackoverflow.com/a/38479643/1617295   -  person Raffi    schedule 20.07.2016


Ответы (3)


Это функциональный тест (поскольку вы просматриваете представление, возможно, запросите модель, если сохраните ее, и т. д.).

Для форм django-webtest намного проще в использовании; вам не придется беспокоиться об этих деталях: https://pypi.python.org/pypi/django-webtest

person François Constant    schedule 04.09.2013

Django теперь реализовал assertFormsetError.

django-basetestcase имеет функцию это позволит вам протестировать formset отдельно от view, не требуя response.

formset = MyFormSet(formset_data)

self.formset_error_test(
    formset,
    form_index=3,
    field='my_field',
    message='My error message.'
)
person Carl Brubaker    schedule 06.04.2019
comment
Не публикуйте ссылку на инструмент или библиотеку в качестве ответа. Продемонстрируйте как это решает проблему в самом ответе. Сделайте отредактируйте ответ и отметьте для восстановления после добавления демонстрации. - person Bhargav Rao; 06.04.2019

Как вы заметили, аргумент имени формы в assertFormError на самом деле является просто ключом в response.context_data. Ключ, который вы используете, возвращает список форм в наборе форм. Итак, как вы обнаружили, это не работает с assertFormError.

Один из вариантов — использовать assertEqual и просто провести прямое сравнение. Что-то типа:

self.assertEqual(response.context_data[u'shareholder_formset'][form_index].errors['share'], 'This field is required.')

Я также хотел бы упомянуть, что моя IDE (PyCharm) очень помогла в этом разобраться. Я работал над похожей проблемой. Включение отладчика, установка точки останова после вызова post() и проверка ответа дали решение.

person Chuck    schedule 15.08.2014