最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to correctly use pytest with Flask and SQLAlchemy - Stack Overflow

programmeradmin3浏览0评论

I am trying to create a pytest suite for my Flask app. To get myself started, I followed several tutorials, notably this, this, this, and this. Now, roughly 5 hours later, I am utterly defeated by the following message:

RuntimeError: The current Flask app is not registered with this 'SQLAlchemy' instance. Did you fet to call 'init_app', or did you create multiple 'SQLAlchemy' instances?

Here is what I did. I created a tests/conftest.py file with the following contents:

import pytest
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

class Config:
    SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:"
    TESTING = True

@pytest.fixture(scope="session")
def app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    db = SQLAlchemy()
    db.init_app(app)

    with app.app_context():
        db.create_all()
        yield app
        db.session.close()
        db.drop_all()

Then, I created a test file called tests/test_db.py:

from app.models import User

def test_init(app):
    with app.app_context():
        id = "0"
        user_query = User.query.filter_by(id=id).first()

I've tried about 573 variations with and without app_context, moving the database init to a separate fixture, using pytest-flask-sqlalchemy, creating clients, app_context().push(), etc. etc. No matter what I do, I either get the The current Flask app is not registered message, or A 'SQLAlchemy' instance has already been registered on this Flask app. Import and use that instance instead.

For good measure, I asked ChatGPT for a working solution, and repeated that request a few times over to try each of its equally non-functioning solutions. But that was to be expected...

So. Could anyone give me an actually working example of how to use pytest with Flask and SQLAlchemy?

I am trying to create a pytest suite for my Flask app. To get myself started, I followed several tutorials, notably this, this, this, and this. Now, roughly 5 hours later, I am utterly defeated by the following message:

RuntimeError: The current Flask app is not registered with this 'SQLAlchemy' instance. Did you fet to call 'init_app', or did you create multiple 'SQLAlchemy' instances?

Here is what I did. I created a tests/conftest.py file with the following contents:

import pytest
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

class Config:
    SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:"
    TESTING = True

@pytest.fixture(scope="session")
def app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    db = SQLAlchemy()
    db.init_app(app)

    with app.app_context():
        db.create_all()
        yield app
        db.session.close()
        db.drop_all()

Then, I created a test file called tests/test_db.py:

from app.models import User

def test_init(app):
    with app.app_context():
        id = "0"
        user_query = User.query.filter_by(id=id).first()

I've tried about 573 variations with and without app_context, moving the database init to a separate fixture, using pytest-flask-sqlalchemy, creating clients, app_context().push(), etc. etc. No matter what I do, I either get the The current Flask app is not registered message, or A 'SQLAlchemy' instance has already been registered on this Flask app. Import and use that instance instead.

For good measure, I asked ChatGPT for a working solution, and repeated that request a few times over to try each of its equally non-functioning solutions. But that was to be expected...

So. Could anyone give me an actually working example of how to use pytest with Flask and SQLAlchemy?

Share Improve this question asked Jan 29 at 20:34 MPAMPA 2,0382 gold badges28 silver badges55 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 0

Maybe it is something with how you set up a test client. From the first glance it looks okay. I did something similar but used a postgres database for testing.

# a single method to create app for both testing and running
def create_app():
   app = Flask(
        __name__,
   )
   app.config.from_object(config_class)
   db.init_app(app) # <- this db is the same which you are using in the main app
   Migrate(app, db)

   # register endpoints
   # app.register_blueprint(some_blp)

   return app


@pytest.fixture(scope="session")
def app():
    test_app = construct_app(app)

    with test_app.test_client() as cl:
        with test_app.app_context():
            db.create_all()
        yield cl
        with test_app.app_context():
            db.sessionmit()
            db.drop_all()

This setup should work.

You can check my pet project (repo) which I did in the past where I also wrote tests. It was one of the first projects I had written on flask so there things I would do differently.

发布评论

评论列表(0)

  1. 暂无评论