I tried to write some test for a basic app using playhouse.flask_utils.FlaskDB and sqlite but I couldn't manage to make it work with flask.Flask.test_client. This is a tool coming with Flask allowing to make easily request against the app.
Some documentation on the subject would be welcome as test are an important part of an application. I spend a couple of day on the problem then I moved the use bare peewee, without FlaskDB.
Welllll... based on your issue description, there's not really anything I can go off of besides that it didn't work for your tests. Can you provide me with something I can reproduce? Some code that exemplifies the issue? What "not working" actually means?
I wrote a small gist with a small flask app using FlaskDB (30 lines) and a test:
https://gist.github.com/gkrnours/f2fa9609617c27dd7dc621eff8eb898e
The test try to follow http://flask.pocoo.org/docs/0.12/testing/#testing
The app run as excepted but the test fail when using the test_client with peewee.OperationalError: Connection already open.
Maybe I'm doing something wrong.
Traceback (most recent call last):
File "test.py", line 22, in test_client
self.app.get("/")
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/werkzeug/test.py", line 778, in get
return self.open(*args, **kw)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/testing.py", line 127, in open
follow_redirects=follow_redirects)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/werkzeug/test.py", line 751, in open
response = self.run_wsgi_app(environ, buffered=buffered)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/werkzeug/test.py", line 668, in run_wsgi_app
rv = run_wsgi_app(self.application, environ, buffered=buffered)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/werkzeug/test.py", line 871, in run_wsgi_app
app_rv = app(environ, start_response)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1994, in __call__
return self.wsgi_app(environ, start_response)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1610, in full_dispatch_request
rv = self.preprocess_request()
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/flask/app.py", line 1831, in preprocess_request
rv = func()
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/playhouse/flask_utils.py", line 171, in connect_db
self.database.connect()
File "/home/gkr/work/web/peewee-flask/nv/lib/python3.4/site-packages/peewee.py", line 3652, in connect
raise OperationalError('Connection already open')
peewee.OperationalError: Connection already open
The error seems pretty clear to me. Are you opening a database connection (even implicitly, to create tables, for instance) anywhere in your tests? If so, be sure to close it. The FlaskDB helper binds handlers to the request setup/teardown cycle in which it connects/closes, respectively. If there's already a connection open in the given thread in which the request is run, then you'll see the above error. It's not a bug, it's a sign to you that you've left a connection dangling somewhere.
I do not leave open connection. FlaskDB do when used with the Flask test_client.
The only time I open the database is for creating the table and I close it 2 line after opening it.
That's the whole point of the issue, I had to choose between FlaskDB and testing my application.
Sorry, reopening to look into this more.
I see the issue. The problem is that you're initializing the database once for every test-case. Because there are two test-cases, the database gets "init_app()" called twice. Inside db.init_app(), handlers are bound to the app's before_request() and request_teardown() hooks. Inside the before_request() hook, the conn is opened.
The problem can be resolved by only calling app.init_db() once. Your app is essentially a singleton object so it maintains its state from run to run.
Not a bug in peewee, but in the way you're setting up your tests. Hope that makes sense.
The explanation make sense yes.
Most helpful comment
I wrote a small gist with a small flask app using FlaskDB (30 lines) and a test:
https://gist.github.com/gkrnours/f2fa9609617c27dd7dc621eff8eb898e
The test try to follow http://flask.pocoo.org/docs/0.12/testing/#testing
The app run as excepted but the test fail when using the test_client with peewee.OperationalError: Connection already open.
Maybe I'm doing something wrong.