使用Flask和Python 3测试文件上载

ste*_*ppl 11 python unit-testing flask python-3.x

我正在使用Flask和Python 3.3,我知道支持仍然是实验性的,但我在尝试测试文件上传时遇到了错误.我正在使用unittest.TestCase并基于我在我尝试的文档中看到的Python 2.7示例

rv = self.app.post('/add', data=dict(
                               file=(io.StringIO("this is a test"), 'test.pdf'),
                           ), follow_redirects=True)
Run Code Online (Sandbox Code Playgroud)

并得到

TypeError: 'str' does not support the buffer interface
Run Code Online (Sandbox Code Playgroud)

我在io.StringIO周围尝试了一些变化,但找不到任何有用的东西.任何帮助深表感谢!

完整的堆栈跟踪是

Traceback (most recent call last):
  File "archive_tests.py", line 44, in test_add_transcript
    ), follow_redirects=True)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 771, in post
    return self.open(*args, **kw)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/flask/testing.py", line 108, in open
    follow_redirects=follow_redirects)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 725, in open
    environ = args[0].get_environ()
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 535, in get_environ
    stream_encode_multipart(values, charset=self.charset)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 98, in stream_encode_multipart
    write_binary(chunk)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 59, in write_binary
    stream.write(string)
TypeError: 'str' does not support the buffer interface
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 14

在Python 3中,您需要使用io.BytesIO()(带有字节值)来模拟上传的文件:

rv = self.app.post('/add', data=dict(
                               file=(io.BytesIO(b"this is a test"), 'test.pdf'),
                           ), follow_redirects=True)
Run Code Online (Sandbox Code Playgroud)

请注意b'...'定义bytes文字的字符串.

在Python 2测试示例中,StringIO()对象包含字节字符串,而不是unicode值,在Python 3中,io.BytesIO()它是等效的.

  • 如果您使用的是实际文件而不是BytesIO,请记住以二进制模式打开它,使用``open('filename.data','rb')`` (5认同)