如何仅提供HTML源代码的表单?

时间:2008-12-05 12:02:54

标签: python django testing parsing form-submit

我希望能够在 HTML源代码(字符串)中提交表单。换句话说,我至少需要能够从包含格式的HTML源的字符串生成POST参数。这在Django项目的单元测试中是必需的。我想要一个可能的解决方案;

  • 仅使用标准Python库和Django。
  • 如果存在多个表单,则允许从特定表单生成参数。
  • 允许我在提交前更改值。

从给定的表单类返回(Django)表单实例的解决方案是最好的。因为它允许我使用验证。理想情况下,它将使用源(字符串),表单类和表单名称,并在呈现之前返回实例。

注意:我知道这不是一件容易的事,可能收益很难证明所需的努力是正确的。但我只是对以实际和可靠的方式如何做到这一点感到好奇。如果可能的话。

4 个答案:

答案 0 :(得分:4)

您应该重新阅读documentation about Django's testing framework,特别是有关使用the test client测试观看次数(和表单)的部分。

测试客户端充当简单的Web浏览器,允许您向Django视图发出GETPOST个请求。您可以阅读响应HTML或获取模板收到的相同Context对象。您的Context对象应包含您要查找的实际forms.Form实例。

例如,如果您在网址/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。

编辑:在我重新阅读有关Forms的Django文档后,结果表明表单是不可变的。但是,没关系,只需创建一个新的Form实例并提交;我已经更改了我的代码示例以匹配此内容。

答案 1 :(得分:2)

由于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。如果它有正确的模板并且具有正确的响应字符串,那么它必须是正确的。

答案 2 :(得分:2)

这很简单......同时也很难 免责声明:我对Python并不了解,也没有任何关于Django的内容......所以我给出了一般的,与语言无关的建议...... 如果上述建议之一不适合您,您可能希望手动执行此操作:

  • 使用HTML解析器加载页面,列出表单。
  • 如果method属性为POST(不区分大小写),请获取action属性以获取请求的URL(可以是相对的)。
  • 在表单中,获取所有inputselect标记。 name(或id,如果没有名称)属性是请求参数的键。 value属性(如果不存在则为空)是相应的值。
  • 对于select,该值是选定的option之一,或者显示的文字不是value属性。

这些名称和值必须在GET请求中进行URL编码,但不能在POST中进行编码。

HTH。

答案 3 :(得分:0)

查看mechanize或它的包装twill。我认为ClientForm模块适合你。