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