Как отправить форму, указав только исходный код HTML? - PullRequest
0 голосов
/ 05 декабря 2008

Я хотел бы иметь возможность отправить форму в источнике HTML (строка) . Другими словами, мне нужна, по крайней мере, возможность генерировать параметры POST из строки, содержащей исходный HTML-код формы . Это необходимо в модульных тестах для проекта Django. Я хотел бы решение, которое возможно;

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

Лучше всего решение, которое возвращает (Django) экземпляр формы из заданного класса формы. Потому что это позволило бы мне использовать проверку. В идеале он потребляет источник (который является строкой), класс формы и, необязательно, имя формы и возвращает экземпляр как он был до рендеринга.

ПРИМЕЧАНИЕ: я знаю, что это нелегкая задача, и, вероятно, выигрыш вряд ли оправдает необходимые усилия. Но мне просто интересно, как это можно сделать практичным и надежным способом. Если возможно.

Ответы [ 4 ]

4 голосов
/ 06 декабря 2008

Вам следует перечитать документацию о структуре тестирования Django , в частности, часть о тестировании представлений (и форм) с помощью тестового клиента .

Тестовый клиент действует как простой веб-браузер и позволяет отправлять GET и POST запросов на ваши представления Django. Вы можете прочитать ответ HTML или получить тот же Context объект, который получил шаблон. Ваш Context объект должен содержать фактический forms.Form экземпляр, который вы ищете.

Например, если ваш взгляд на URL /form/ передает контекст {'myform': forms.Form()} в шаблон, вы можете получить его следующим образом:

from django.test.client import Client
c = Client()

# request the web page:
response = c.get('/form/')

# get the Form object:
form = response.context['myform']

form_data = form.cleaned_data
my_form_data = {} # put your filled-out data in here...
form_data.update(my_form_data)

# submit the form back to the web page:
new_form = forms.Form(form_data)
if new_form.is_valid():
    c.post('/form/', new_form.cleaned_data)

Надеюсь, это достигнет того, что вы хотите, без необходимости возиться с анализом HTML.

Редактировать : После того, как я перечитал документы Django о формах, оказывается, что формы неизменны. Это нормально, однако, просто создайте новый экземпляр Form и отправьте его; Я изменил свой пример кода, чтобы соответствовать этому.

2 голосов
/ 05 декабря 2008

Это просто ... и тяжело одновременно.
Отказ от ответственности: я не знаю много о Python и совсем ничего о Django ... Так что я даю общие, независимые от языка советы ... Если один из вышеперечисленных советов не работает для вас, вы можете сделать это вручную:

  • Загрузите страницу с анализатором HTML, перечислите формы.
  • Если атрибут method имеет значение POST (без учета регистра), получите атрибут action, чтобы получить URL-адрес запроса (может быть относительным).
  • В форме получите все теги input и select. Атрибуты name (или id, если имени нет) являются ключами параметров запроса. Атрибуты value (пустые, если отсутствуют) являются соответствующими значениями.
  • Для select это значение соответствует выбранному option или отображаемый текст не является атрибутом value.

Эти имена и значения должны быть URL-адресами, закодированными в запросах GET, но не в запросах POST.

НТН.

2 голосов
/ 05 декабря 2008

Поскольку тестовая среда Django делает это, я не уверен, что вы спрашиваете.

Хотите протестировать приложение Django, имеющее форму?

  • В этом случае вам нужно сделать начальный GET
  • с последующим результатом POST

Хотите написать (и протестировать) приложение Django, которое отправляет форму на другой сайт?

Вот как мы тестируем приложения Django с формами.

class Test_HTML_Change_User( django.test.TestCase ):
    fixtures = [ 'auth.json', 'someApp.json' ]
    def test_chg_user_1( self ):
        self.client.login( username='this', password='this' )
        response= self.client.get( "/support/html/user/2/change/" )
        self.assertEquals( 200, response.status_code )
        self.assertTemplateUsed( response, "someApp/user.html")

def test_chg_user( self ):
    self.client.login( username='this', password='this' )
    # The truly fussy would redo the test_chg_user_1 test here
    response= self.client.post(
        "/support/html/user/2/change/",
        {'web_services': 'P',
         'username':'olduser',
         'first_name':'asdf',
         'last_name':'asdf',
         'email':'asdf@asdf.com',
         'password1':'passw0rd',
         'password2':'passw0rd',} )
    self.assertRedirects(response, "/support/html/user/2/" )
    response= self.client.get( "/support/html/user/2/" )
    self.assertContains( response, "<h2>Users: Details for", status_code=200 )
    self.assertContains( response, "olduser" )
    self.assertTemplateUsed( response, "someApp/user_detail.html")

Примечание - мы не разбираем HTML подробно. Если у него правильный шаблон и правильная строка ответа, он должен быть правильным.

0 голосов
/ 05 декабря 2008

Выезд Механизация или его обертка Твил . Я думаю, что ClientForm модуль будет работать для вас.

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