I am trying to implement unit testing to my Flask application. In this function I am trying to search an image in my database by a keyword.
Search image in database file:
from models import ImageKeyword, Image
import random
keyword_limit_in_database = 100
def search_image_in_db(keyword):
query = ImageKeyword.query.filter_by(keyword=keyword) # query for keyword table
row_count = int(query.count()) # row count for keywords
if row_count > keyword_limit_in_database:
image_keyword = query.offset(int(row_count * random.random())).first()
if image_keyword is not None:
image = Image.query.filter_by(id=image_keyword.image_id).first()
if image is not None:
return image # found Image in our database by keyword
Here is my current test function:
from image_search import image_search_in_db
def test_search_image_in_db():
keyword = "sun"
result = image_search_in_db.search_image_in_db(keyword)
assert result is not None
The image with a keyword "sun" currently is in my database. The error code I am receiving when running pytest:
self = <sqlalchemy.util._collections.ScopedRegistry object at 0x7f2e42b75b10>
def __call__(self):
key = self.scopefunc()
try:
> return self.registry[key]
E KeyError: <greenlet.greenlet object at 0x7f2e440fa3c0>
/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/_collections.py:1030: KeyError
During handling of the above exception, another exception occurred:
def test_search_image_in_db():
keyword = "sun"
> result = image_search_in_db.search_image_in_db(keyword)
TestCases/test_search_in_db.py:6:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
image_search/image_search_in_db.py:8: in search_image_in_db
query = ImageKeyword.query.filter_by(keyword=keyword) # query for keyword table
/usr/local/lib/python3.7/dist-packages/flask_sqlalchemy/__init__.py:519: in __get__
return type.query_class(mapper, session=self.sa.session())
/usr/local/lib/python3.7/dist-packages/sqlalchemy/orm/scoping.py:78: in __call__
return self.registry()
/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/_collections.py:1032: in __call__
return self.registry.setdefault(key, self.createfunc())
/usr/local/lib/python3.7/dist-packages/sqlalchemy/orm/session.py:3254: in __call__
return self.class_(**local_kw)
/usr/local/lib/python3.7/dist-packages/flask_sqlalchemy/__init__.py:136: in __init__
self.app = app = db.get_app()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <SQLAlchemy engine=None>, reference_app = None
def get_app(self, reference_app=None):
"""Helper method that implements the logic to look up an
application."""
if reference_app is not None:
return reference_app
if current_app:
return current_app._get_current_object()
if self.app is not None:
return self.app
raise RuntimeError(
> 'No application found. Either work inside a view function or push'
' an application context. See'
' http://flask-sqlalchemy.pocoo.org/contexts/.'
)
E RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
/usr/local/lib/python3.7/dist-packages/flask_sqlalchemy/__init__.py:982: RuntimeError
=================================================================================================== short test summary info ===================================================================================================
FAILED TestCases/test_search_in_db.py::test_search_image_in_db - RuntimeError: No application found. Either work inside a view function or push an application context.
I think the issue is that my application during the test is unable to connect to my database. I have 3 environments, local, development and production. I have set up that when running the application PyCharm would select the local environment. Should I connect to my database in my test file or maybe I could set the environment in my test file, I am not sure how to do that.I am new to testing. Any help will be appreciated.
app.py file content:
from flask import Flask, render_template, session
from models import db
from flask_restful import Api
from flask_socketio import SocketIO, emit
from controllers.image_controller import ImageController
from controllers.question_controller import model
from flask_cors import CORS
app = Flask(__name__)
app.config.from_object("config.Config")
app.config['SECRET_KEY'] = '123456'
db.init_app(app)
socketio = SocketIO(app, cors_allowed_origins='*')
api = Api(app)
CORS(app)
api.add_resource(ImageController, '/images')
@app.route('/chatbot')
def index():
return render_template('index.html', async_mode=socketio.async_mode)
@socketio.on('my_event', namespace='/chatbot')
def test_message(question):
answer = model.get_answer(question['data'])
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response', {'data': answer})
if __name__ == '__main__':
socketio.run(app, host="0.0.0.0", debug=True, use_reloader=False)
The current error I am receiving:
FAILED TestCases/test_search_in_db.py::test_search_image_in_db - NameError: name 'create_app' is not defined
It seems the app context is missing when you running the test case. Try:
def test_search_image_in_db():
app=create_app()
with app.app_context():
keyword = "sun"
result = image_search_in_db.search_image_in_db(keyword)
assert result is not None
You can use a pytest fixture to create app once per test session and make it available in all test case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With