34

ニュースのモデレートのためにSqlAlchemyを使用してFlaskでWebアプリケーションを動作させています.承認、現在選択されているニュースの拒否、リストなどのモデレーションリクエストを処理するいくつかのAPIメソッドがあります.

このメソッドに単体テストを書きたいのですが、それらを機能させましたが、データベースへのすべての変更を削除できるように、1 つの db セッションでテスト ケースから行うすべての要求の実行を実装する方法がわかりません。または、これを行うための別のクリーンまたは適切な方法はありますか?

おそらく必要なのは SqlAlchemy の「scoped_session」だけであることがわかりましたが、それを実装する試みはすべて失敗しました。それが正しい方法である場合は、このコード行を使用する場所を教えてください (設定、またはテスト ケースの set_up メソッド)。

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

3 に答える 3

29

Flask-Testing拡張機能を使用することをお勧めします。これは承認済みの拡張機能であり、必要に応じて単体テストを実行できます。SQLAlchemy の特定のセクションもあります。

SQLAlchemy を使用したテスト

SQLAlchemy で Flask-Testing を使用している場合、これはいくつかの点をカバーしています。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()
于 2013-07-22T16:14:32.213 に答える
17

これは、私が最近単体テストを実行している方法です。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()

アプリと同じ DB セットアップを使用しているため、実行するすべての単体テストでテスト データベースを構築および破棄できます。

于 2013-07-23T18:58:41.000 に答える
14

Flask-Testing を使用した codegeek の回答については、何をするのか理解できcreateapp()ません。Flask-SqlAlchemy Introduction into Contextsは、SQLAlchemy オブジェクトをアプリケーションに動的にバインドする方法についての指針を提供してくれました。この場合、テスト アプリケーションにバインドします。

基本的:

  1. フラスコの sqlalchemy オブジェクトを作成しますが、アプリ オブジェクトは渡さないでください。
  2. 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

次に、Flask-Test Documentation で概説されているように、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 オブジェクトを動的にバインドできることです。各アプリケーションは、さまざまな目的に使用できます。たとえば、1 つは本番用、もう 1 つは単体テスト用です。プロダクションの場合、最上位のフラスコ アプリケーションで create_production_application() を呼び出すことができます。

于 2016-08-08T08:44:23.950 に答える