@kotyのブログ

PythonとかAWSとか勉強会のこととかを、田舎者SEがつづります。記事のライセンスは"CC BY"でお願いします。

migrateをスキップすることでDjangoのunittestを高速化する

この記事には以下の追記がありますので、あわせてお読みください。

koty.hatenablog.com

modelが大きくなってきたり、migration ファイルが増えると、unit testの最初に流れるmigrationのせいでテストの実行に時間がかかるようになる。そこで高速化を試みた。

作戦としては、

  1. migrate済みのsqliteファイルを用意しておく
  2. テスト実行時にsqliteファイルをコピーする
  3. migrationをスキップしつつ、コピーしたファイルに対しテストを実行する

ということを考えた。

migrationのスキップ方法はここに書いてある通り。

simpleisbetterthancomplex.com

というわけで、以下のような設定を追記するとうまくいく。これで実行時間が半分になった。*1

import shutil
# あらかじめmigrate済みの空のファイルdb_test.sqlite3.template を配置しておく
shutil.copyfile(os.path.join(BASE_DIR, '../db_test.sqlite3.template'),
                os.path.join(BASE_DIR, '../db_test.sqlite3'))
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, '../db_test.sqlite3'),
    }
}


class DisableMigrations(object):
    def __contains__(self, item):
        return True

    def __getitem__(self, item):
        # return 'notmigrations'
        return False  # django 1.11にも対応するにはこちらで

MIGRATION_MODULES = DisableMigrations()

modelに変更があったら、コピー元のsqliteファイルもmigrateする必要があるのがイマイチな点。もっと良い方法があれば教えてください。

ここ2年djangoを使っているが初めての記事になってしまった。もう少しアウトプットしたい。。

Two Scoops of Django: Best Practices for Django 1.8

Two Scoops of Django: Best Practices for Django 1.8

*1:‘notmigrations’ の意味がイマイチわからなかった。djangoのソースをgrepしても該当がないし。