Testing file upload with Flask and Python 3
flask, python, python-3.x, unit-testing
Solution
In Python 3, you need to use `io.BytesIO()` (with a bytes value) to simulate an uploaded file:
rv = self.app.post('/add', data=dict(
file=(io.BytesIO(b"this is a test"), 'test.pdf'),
), follow_redirects=True)
Note the `b'...'` string defining a `bytes` literal.
In the Python 2 test examples, the `StringIO()` object holds a byte string, not a `unicode` value, and in Python 3, `io.BytesIO()` is the equivalent.
Problem
I'm using Flask with Python 3.3 and I know support is still experimental but I'm running into errors when trying to test file uploads. I'm using `unittest.TestCase` and based on Python 2.7 examples I've seen in the docs I'm trying ``` rv = self.app.post('/add', data=dict( file=(io.StringIO("this is a test"), 'test.pdf'), ), follow_redirects=True) ``` and getting ``` TypeError: 'str' does not support the buffer interface ``` I've tried a few variations around io.StringIO but can't find anything that works. Any help is much appreciated! The full stack trace is ``` 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 ```