Reputation: 2038
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 forget 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?
Upvotes: 1
Views: 77
Reputation: 724
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.session.commit()
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.
Upvotes: 0