pytest тестирование Flask приложения с тестовой базой данных
test
from webapp import db
def test_new_user():
new_user = UserModel(email='[email protected]', is_active=False)
db.session.add(new_user)
db.session.commit()
proj/webapp/__init__.py
db = SQLAlchemy()
def create_app(object_name):
app = Flask(__name__)
app.config.from_object(object_name)
db.init_app(app)
...
return app
proj/main.py
from webapp import create_app
env = os.environ.get("WEBAPP_ENV", "dev")
app = create_app("config.%sConfig" % env.capitalize())
if __name__ == "__main__":
app.run()
Когда запускаю тест pytest -v - получаю ошибку RuntimeError: No application found. Either work inside a view function or push an application context
Нужно как-то инициализировать тестовую бд (желательно на постгресе, хотя сойдёт и sqlite для тестов, думаю). В доке есть раздел об этом
Попытался сделать также
def get_db():
if 'db' not in g:
g.db = sqlite3.connect(
'sqlite.db',
detect_types=sqlite3.PARSE_DECLTYPES
)
g.db.row_factory = sqlite3.Row
return g.db
В итоге тест превратился в это
def test_new_user():
with app.app_context():
db = get_db()
new_user = UserModel(email='[email protected]', is_active=False)
db.session.add(new_user)
db.commit()
dir(db)
# ['DataError', 'DatabaseError', 'Error', 'IntegrityError', 'InterfaceError', 'InternalError', 'NotSupportedError', 'OperationalError', 'ProgrammingError', 'Warning', '__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'backup', 'close', 'commit', 'create_aggregate', 'create_collation', 'create_function', 'cursor', 'execute', 'executemany', 'executescript', 'in_transaction', 'interrupt', 'isolation_level', 'iterdump', 'rollback', 'row_factory', 'set_authorizer', 'set_progress_handler', 'set_trace_callback', 'text_factory', 'total_changes']
type(db) # <class 'sqlite3.Connection'>
db #<sqlite3.Connection object at 0x7f9abd885f10>
Соответственно, атрибута session у этого объекта нет.