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 01 Answer
Reset to default 0Maybe 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.