0

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

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

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

注意:我知道这不是一件容易的事,而且可能收益很难证明所需要的努力是合理的。但我只是好奇如何以一种实用且可靠的方式做到这一点。如果可能的话。

4

4 回答 4

4

您应该重新阅读有关 Django 测试框架的文档,特别是有关使用测试客户端测试视图(和表单)的部分。

测试客户端充当一个简单的 Web 浏览器,并允许您向 Django 视图发出GETPOST请求。您可以阅读响应 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实例并提交即可;我已经更改了我的代码示例以匹配此。

于 2008-12-05T22:08:09.743 回答
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。如果它有正确的模板和正确的响应字符串,它必须是正确的。

于 2008-12-05T12:10:32.073 回答
2

这很简单……同时也很困难。
免责声明:我对 Python 知之甚少,对 Django 一无所知...所以我给出一般的、与语言无关的建议...如果上述建议之一对您不起作用,您可能需要手动执行:

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

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

HTH。

于 2008-12-05T13:16:50.207 回答
0

检查机械化或它的包装斜纹布。我认为它的ClientForm模块会为你工作。

于 2008-12-05T12:59:34.220 回答