My Django単体テストの実行には時間がかかるので、それを高速化する方法を探しています。 [〜#〜] ssd [〜 #〜] 、しかし、それにも欠点があることは知っています。もちろん、コードでできることはありますが、構造的な修正を探しています。毎回再構築/南に移行するため、ここに私のアイデアがあります...
テストデータベースは常に非常に小さいことがわかっているので、テストデータベース全体を常にRAMに保持するようにシステムを構成できないのはなぜですか?ディスクには絶対に触れないでください。 Djangoでこれを設定するにはどうすればよいですか? MySQL を使用し続けたいと思いますが、これは本番環境で使用しているものですが、 SQLite 3または他の何かがこれを簡単にするなら、私はそのようにします。
SQLiteまたはMySQLには、完全にメモリ内で実行するオプションがありますか? RAMディスクを構成してから、テストデータベースを構成してそのデータをそこに格納することは可能ですが、Django/MySQLは特定のデータベースに別のデータディレクトリを使用します。特に、実行ごとに消去され、再作成されるためです(Mac FWIWを使用しています)。
テストの実行時にデータベースエンジンをsqlite3に設定すると、 Djangoはメモリ内データベースを使用します 。
私のsettings.py
で次のようなコードを使用して、テストの実行時にエンジンをsqliteに設定しています。
if 'test' in sys.argv:
DATABASE_ENGINE = 'sqlite3'
またはDjango 1.2:
if 'test' in sys.argv:
DATABASES['default'] = {'ENGINE': 'sqlite3'}
そして最後にDjango 1.3および1.4:
if 'test' in sys.argv:
DATABASES['default'] = {'ENGINE': 'Django.db.backends.sqlite3'}
(Django 1.3の場合、バックエンドへの完全なパスは必ずしも必要ではありませんが、設定は前方互換性があります。)
Southの移行に問題がある場合は、次の行を追加することもできます。
SOUTH_TESTS_MIGRATE = False
私は通常、テスト用に個別の設定ファイルを作成し、テストコマンドで使用します。
python manage.py test --settings=mysite.test_settings myapp
2つの利点があります。
Sys.argvでtest
またはそのようなマジックワードを確認する必要はありません、test_settings.py
は単に
from settings import *
# make tests faster
SOUTH_TESTS_MIGRATE = False
DATABASES['default'] = {'ENGINE': 'Django.db.backends.sqlite3'}
または、ニーズに合わせてさらに微調整して、テスト設定と運用設定を明確に分離することもできます。
別の利点は、微妙なバグを回避するために、sqlite3の代わりに本番データベースエンジンでテストを実行できることです。
python manage.py test --settings=mysite.test_settings myapp
コードをコミットする前に1回実行する
python manage.py test myapp
すべてのテストが本当に合格していることを確認するだけです。
MySQLは、「MEMORY」というストレージエンジンをサポートしています。これは、データベース構成で構成できます(settings.py
) など:
'USER': 'root', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'OPTIONS': {
"init_command": "SET storage_engine=MEMORY",
}
MEMORYストレージエンジンはblob/text列をサポートしていないことに注意してください。したがって、Django.db.models.TextField
これはあなたには機能しません。
主な質問に答えることはできませんが、速度を上げるためにできることがいくつかあります。
まず、MySQLデータベースがInnoDBを使用するように設定されていることを確認してください。その後、トランザクションを使用して各テストの前にdbの状態をロールバックできますが、これは私の経験では大幅な高速化につながりました。 settings.pyでデータベース初期化コマンドを渡すことができます(Django 1.2構文):
DATABASES = {
'default': {
'ENGINE':'Django.db.backends.mysql',
'Host':'localhost',
'NAME':'mydb',
'USER':'whoever',
'PASSWORD':'whatever',
'OPTIONS':{"init_command": "SET storage_engine=INNODB" }
}
}
第二に、毎回南の移行を実行する必要はありません。 settings.pyでSOUTH_TESTS_MIGRATE = False
を設定すると、データベースは単純なsyncdbで作成されます。これは、すべての歴史的な移行を実行するよりもはるかに高速です。
あなたは二重調整を行うことができます:
私は両方のトリックを使用していますが、とてもうれしいです。
UbuntuでMySQL用に設定する方法:
$ Sudo service mysql stop
$ Sudo cp -pRL /var/lib/mysql /dev/shm/mysql
$ vim /etc/mysql/my.cnf
# datadir = /dev/shm/mysql
$ Sudo service mysql start
データベースをメモリから再起動すると失われるため、テスト用です。
別のアプローチ:RAM Disk。を使用するtempfsでMySQLの別のインスタンスを実行します。このブログ投稿の手順: Django でテストしています。
利点:
Anuragの答えを拡張して、同じtest_settingsを作成し、manage.pyに以下を追加することでプロセスを簡素化しました
if len(sys.argv) > 1 and sys.argv[1] == "test":
os.environ.setdefault("Django_SETTINGS_MODULE", "mysite.test_settings")
else:
os.environ.setdefault("Django_SETTINGS_MODULE", "mysite.settings")
sysはすでにインポートされており、manage.pyはコマンドライン経由でのみ使用されるため、設定を乱雑にする必要がないため、よりクリーンに見えます