Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pytest RuntimeError: No application found. Either work inside a view function or push an application context

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
like image 601
Dave Avatar asked Sep 05 '25 03:09

Dave


1 Answers

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.

like image 71
anunaki Avatar answered Sep 07 '25 19:09

anunaki