admin管理员组

文章数量:1316219

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.

本文标签: How to correctly use pytest with Flask and SQLAlchemyStack Overflow