【问题标题】:Simulating a Google App Engine File Upload in Python在 Python 中模拟 Google App Engine 文件上传
【发布时间】:2011-08-09 03:08:54
【问题描述】:

我有一个 Python 版本的 Google App Engine 应用程序,可让用户上传文件。提交文件后,我使用

获取文件
self.request.get('uploaded_file')

我使用

获取文件名
self.request.POST['uploaded_file'].filename 

我正在尝试通过手动创建一个 webapp 请求来为它编写一个单元测试,文件设置为我想要的方式。但是,我不知道如何初始化它,以便我可以获取上传的文件及其文件名。

有什么想法吗?

【问题讨论】:

  • 我不确定是否可以测试 blobstore 功能。当您生成要上传到它的链接时,假定完成后有服务器在端口上侦听以在完成上传时调用处理程序。如果你没有运行 devappserver,你就不会得到它。
  • 应用程序不使用 blobstore 或实际提供文件——它只是让用户上传文件来验证它。它使用标准的 HTTP POST,将其放入请求对象中,以便处理程序使用我实现的 post() 方法进行响应。
  • 我不知道您可以这样做,我认为 appengine 不允许带有文件的表单帖子路由到您的应用程序,因为它会无限期地占用一个实例。我想情况并非如此。

标签: python unit-testing google-app-engine file-upload


【解决方案1】:

如果您正在测试您的处理程序,您可能已经创建了一个 Webob 请求对象并将其传递给您的处理程序,如下所示:

request = webapp.Request({
    "wsgi.input": StringIO.StringIO(),
    "METHOD": "POST",
})
response = webapp.Response()
handler = MyHandler()
handler.initialize(request, response)
handler.post()

上传的文件是cgi.FieldStorage 对象,但FieldStorage 并不是特别容易测试。相反,使用模拟框架(例如 mox)来创建模拟可能是最简单的,或者只是创建一个简单的假:

class FakeFieldStorage(object):
  def __init__(self, filename, value):
    self.filename = filename
    self.value = value

然后创建一个并将其添加到请求对象中,然后再将其传递给处理程序:

uploaded_file = FakeFieldStorage("test.txt", "foo")
request.POST['file'] = uploaded_file

【讨论】:

  • 是的,这正是我所做的,我在使用 FieldStorage 进行测试时遇到了问题。我必须使用REQUEST_METHOD 而不是METHOD 才能意识到我的请求是一个POST。我还必须添加def __repr__(self): return self.value 以使FakeFieldStorage 表现得像普通的FieldStorage 这样self.request.get('uploaded_file') 就可以按预期工作,但这成功了。谢谢!
  • @Sam 请记住,在这种情况下,self.request.get('uploaded_file') 只是 str(self.request.POST['uploaded_file']) 的语法糖,它是特定于 webapp 的。只使用 webob 方法会更好——通常也更容易。
【解决方案2】:

通过让测试使用urlopen 或类似方法实际发送带有附加到您的应用的文件的请求来测试它。

然后验证响应和上传后的状态。

【讨论】:

  • 致反对者:见stackoverflow.com/privileges/vote-down。我不认为我的答案接近满足这些标准。如果您认为是,请发表评论解释您的问题。
  • 我可能无法 100% 理解您的建议。听起来您建议启动服务器并实际向它发送请求。我正在尝试测试文件上传是否正常工作,并且我想在单元测试而不是服务器测试中执行此操作,这意味着它应该快速运行(没有实际启动应用程序引擎开发服务器的开销,以便它可以响应 URL)并且应该只测试响应上传文件的函数(而不测试其他页面是否正常工作)。
  • 我建议您让您的脚本实际上将文件发送到服务器,方法是像任何网页一样打开它,通过它的 url,使用urlopen,在POST 中有一个文件数据,就像用户上传到网站一样。编辑:您更新了您的评论。如果不这样做,我认为您无法准确地测试它。
猜你喜欢
  • 2010-09-10
  • 2013-08-25
  • 1970-01-01
  • 2016-01-18
  • 2010-10-24
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多