@kotyのブログ

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

Django2系でのunit testにおけるno migration設定

この記事は、Django Advent Calendar 2018 - QiitaおよびJSL (日本システム技研) Advent Calendar 2018 - Qiitaの17日めの記事です。(相乗りすみません)

こちらの続き。

koty.hatenablog.com

結論としては、以下で実現できる。

from .base import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': ':memory:',
    }
}

# MIGRATION_MODULESは各installed_appsにある名前をkeyに、当該appのmigrationファイルのモジュール(既定ではmigrationsモジュール)をvalue指定した辞書。
# 以下のクラス、どんなキーを指定しても辞書に存在し、どんなキーを指定しても`None`を返す辞書を作っている。
# 'None'モジュールは存在しないので、既存のmigrationファイルは見つからずにmigration未済みという扱いになる。
class DisableMigrations(object):
    def __contains__(self, item):
        return True

    def __getitem__(self, item):
        # return 'notmigrations'
        return None  # django 1.11および2系にも対応するにはこちらで

MIGRATION_MODULES = DisableMigrations()

上記1.11系に対応したときの記事でも FlaseではなくNoneを返しておけば問題なかった。実際、これらの処理をパッケージ化したdjango-test-without-migrationsでは特段の2系対応は入っていない。そもそもこのパッケージを入れておけば良いというウワサもある。。。

DisableMigrationsはDjango内部の挙動をだまくらかすようなhack的なことをしているため、今後のDjangoのバージョンアップで動かなくなる可能性は依然あります。

というわけで、テストを高速化してハッピー開発ライフを送ってください。