我正在尝试对我的Flask应用程序实施单元测试。在此功能中,我试图通过关键字在数据库中搜索图像。
在数据库文件中搜索图像:
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
这是我当前的测试功能:
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
关键字为“ sun”的图像当前在我的数据库中。 运行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.
我认为问题是测试期间我的应用程序无法连接到我的数据库。我有3个环境,分别是本地,开发和生产。我已经设置为在运行应用程序PyCharm时会选择本地环境。我应该在测试文件中连接到数据库,还是可以在测试文件中设置环境,我不确定如何做到这一点。任何帮助将不胜感激。
app.py文件内容:
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)
我收到的当前错误:
FAILED TestCases/test_search_in_db.py::test_search_image_in_db - NameError: name 'create_app' is not defined
答案 0 :(得分:2)
运行测试用例时似乎缺少应用上下文。试试:
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
您可以使用pytest fixture在每个测试会话中创建一次应用,并将其在所有测试案例中都可用。