4

バックエンドとしてmysqlを使用するdjango 1.4プロジェクトがあります。メモリ内で実行するようにテストをセットアップしました

if 'test' in sys.argv:
  DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}

問題は、mysql 機能 (全文インデックス) を使用する必要があることです。

テストのためにメモリ内で django に MySQL を実行させる方法はありますか?

私のプロジェクトはフルテキスト インデックスに依存しています。プロジェクトが I syncdb で開発されている場合.sql、SQL を含むファイルを実行して全文索引を作成します。

テストする機能でdjango orm全文検索を使用したいと思います。次のように、各テストの初期化でフルテキスト インデックスを手動で追加しようとしています。

cursor.execute('alter table mytable add fulltext(one, two)')

sqlite を使用している場合、これは機能しません (sqlite はフルテキスト インデックス作成をサポートしていないためだと思います)。

上記のSQLは、メモリ内テストを削除すると機能します。インメモリテストの速度が気に入っています。 メモリ内で mysql を実行する方法はありますか?

データベース固有の機能に依存するアプリをどのようにテストしますか? 全文索引付けや GIS などのように...ファイルシステム上で通常どおりテストを実行する必要がありますか?

ありがとうございました

4

3 に答える 3

14

MySQL にはMEMORYストレージ エンジンがあります。次のキーを使用してアクティブ化できます。OPTIONS

if 'test' in sys.argv:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': 'localhost',
            'NAME': 'foo',
            'USER': 'bar',
            'PASSWORD': 'baz',
            'OPTIONS': {
                'init_command': 'SET storage_engine=MEMORY'
            }
        }
    }

しかし、ドキュメントによると:

MEMORY tables cannot contain BLOB or TEXT columns.

したがって、あなたの(および他の多くの)ユースケースにはほとんど役に立たないと思います。

このスレッドで、MySQL テストを高速化するためのヒントをいくつか見つけました。INNODBエンジンの使用に関する Daniel Roseman の回答を必ずお読みください。

于 2013-03-05T23:06:38.123 に答える
3

monkut が質問のコメントで示唆したように、テスト データベースを RAM ドライブに保存することで、MySql の速度を向上できる場合があります。たとえば、Linux で実行している場合は tmpfs ファイルシステム。ただし、テスト中の速度が気になる場合は、MySql は通常データをメモリにキャッシュするため、速度はあまり改善されない可能性があります。

私が使用したアプローチは、特定のデータベース バックエンドでサポートされていないテストをスキップするテスト デコレータを作成し、別のsettings.pyファイルを使用して別のバックエンドに対するテストを行うというものです。

ここでは、django-nose機能を使用して、SQLite を使用するテスト データベースがある場合にテストをスキップするデコレータを作成できるようにしました。

from nose import SkipTest
from django.conf import settings

def skip_if_sqlite(test_fn):
    """Nose test decorator to skip test if testing using sqlite databases.

    This may be useful when we know that a test will fail when using sqlite,
    possibly because the test uses functionality not supported on sqlite such
    as database views or full text indexes.

    This decorator can be used as follows:
    @skip_if_sqlite
    def my_test_that_shouldnt_run_if_sqlite_database(self):
        pass
    """

    @functools.wraps(test_fn)
    def wrapper(*args, **kwargs):
        # Skip test if any database contain a sqlite engine.
        for alias, db_settings in settings.DATABASES.iteritems():
            if 'sqlite' in db_settings['ENGINE']:
                raise SkipTest()
            return test_fn(*args, **kwargs)

    return wrapper

次に、さまざまな設定でセットアップしsettings.test.mysqlます。でテストを実行すると、MySql 固有の機能に依存するテストはスキップされますが、 に対してテストを実行すると、テストが実行されます。settings.test.sqliteDATABASEsettings.test.sqlitesettings.test.mysql

このアプローチにより、特定のデータベース バックエンドでテストを明確にターゲットにすることができますが、開発中に高速な SQLite データベースに対してテストの大部分を実行する柔軟性も提供されます。

于 2013-03-06T00:05:08.207 に答える
-4

MySQL をテストしないでください。MySQL は開発者によってテストされています。あなたの仕事は、MySQL 接続を、MySQL が返すものを返すモック Python オブジェクトで置き換えることができるようにコーディングすることです (または、MySQL に送信されるクエリがあなたが望むものであるかどうかをアサートします)。

于 2013-03-05T23:33:17.777 に答える