Тестовая колба sql alchemy - программирование

Тестовая колба sql alchemy

У меня есть рабочее веб-приложение на Flask с SqlAlchemy для модерации новостей, у него есть некоторые методы api для обработки запросов модерации, таких как одобрение, запрет выбранных новостей, их список и т.д. Я хочу написать модульные тесты для этого методы, и я заставил их работать, но я не понимаю, как реализовать выполнение всех запросов, которые я делаю из тестовых случаев, в одном сеансе db, чтобы я мог удалить все изменения в базе данных. Или есть еще один очиститель или правильный способ сделать это? Я выяснил, что, возможно, все, что мне нужно, это "scoped_session" в SqlAlchemy, но все мои попытки выполнить его не сработали. Если это правильный путь, пожалуйста, скажите мне, где использовать эти строки кода (в настройках или в методе set_up тестового примера).

from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
session_factory = sessionmaker()
Session = scoped_session(session_factory) 
4b9b3361

Ответ 1

Я предлагаю вам использовать расширение Flask-Testing. Это одобренное расширение, которое позволяет выполнять тестирование устройства по вашему желанию. Он также имеет специальный раздел для SQLAlchemy.

Тестирование с помощью SQLAlchemy

Это касается нескольких пунктов, если вы используете Flask-Testing с SQLAlchemy. Предполагается, что вы используете расширение Flask-SQLAlchemy, но если нет, то примеры не должны быть слишком сложными для адаптации к вашей конкретной настройке.

Во-первых, убедитесь, что вы установили URI базы данных в нечто иное, чем ваша производственная база данных! Во-вторых, обычно рекомендуется создавать и отбрасывать таблицы с каждым тестовым прогоном, чтобы обеспечить чистые тесты: "

from flask.ext.testing import TestCase

from myapp import create_app, db

class MyTest(TestCase):

    SQLALCHEMY_DATABASE_URI = "sqlite://"
    TESTING = True

    def create_app(self):

        # pass in test configuration
        return create_app(self)

    def setUp(self):

        db.create_all()

    def tearDown(self):

        db.session.remove()
        db.drop_all()

Ответ 2

Так я недавно тестировал модульные тесты. Я предполагаю, что вы используете SQLAlchemy, что используете классы моделей. Я также предполагаю, что все ваши таблицы определены как классы модели SQLAlchemy.

from flask import Flask
import unittest

from app import db
from app.models import Log
from constants import test_logs

class appDBTests(unittest.TestCase):

    def setUp(self):
        """
        Creates a new database for the unit test to use
        """
        self.app = Flask(__name__)
        db.init_app(self.app)
        with self.app.app_context():
            db.create_all()
            self.populate_db() # Your function that adds test data.

    def tearDown(self):
        """
        Ensures that the database is emptied for next unit test
        """
        self.app = Flask(__name__)
        db.init_app(self.app)
        with self.app.app_context():
            db.drop_all()

Поскольку вы используете тот же БД, который настроен как приложение, это позволяет вам создавать и уничтожать тестовую базу данных с каждым запущенным unit test.

Ответ 3

Что касается ответа codegeek, использующего Flask-Testing, мне трудно понять, что делает createapp(). Flask-SqlAlchemy Введение в контексты предоставило мне некоторый указатель на то, как динамически связывать объект SQLAlchemy с вашим приложением. В этом случае привязка к тестовому приложению.

В основном:

  • Создайте объект sqlalchemy в колбе, но не передайте объект приложения
  • В функции create_app создайте тестовое приложение и динамически привяжите SQLAlchemy.

myapp.py:

# don't pass in the app object yet
db = SQLAlchemy()

def create_test_app():
    app = Flask(__name__)
    app.config['TESTING'] = True
    app.config["SQLALCHEMY_DATABASE_URI"] = "xxxxxxtestdatabasexxx"
    # Dynamically bind SQLAlchemy to application
    db.init_app(app)
    app.app_context().push() # this does the binding
    return app

# you can create another app context here, say for production
def create_production_app():
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "xxxxxxproductionxxxx"
    # Dynamically bind SQLAlchemy to application
    db.init_app(app)
    app.app_context().push()
    return app

Затем вы можете следовать решению codegeek, как описано в документации по фляжке.

from flask.ext.testing import TestCase
from myapp import create_app, db

class MyTest(TestCase):

    # I removed some config passing here
    def create_app(self):
        return create_test_app()

    def setUp(self):

        db.create_all()

    def tearDown(self):

        db.session.remove()
        db.drop_all()

Самое приятное в этом решении заключается в том, что вы можете создавать разные приложения и динамически связывать объект SQLAlchemy с помощью функции. Каждое приложение может использоваться в разных целях. Например, один для производства и один для модульного теста. В случае для производства вы можете вызвать create_production_application() в своем приложении фляги верхнего уровня.