Django 1.7에서 단위 테스트를 실행할 때 마이그레이션 비활성화


110

Django 1.7데이터베이스 마이그레이션을 도입했습니다 .

Django 1.7에서 단위 테스트를 실행하면 시간이 오래 걸리는 migrate를 강제 실행합니다 . 그래서 장고 마이그레이션을 건너 뛰고 최종 상태에서 데이터베이스를 만들고 싶습니다.

마이그레이션을 무시하는 것은 코드의 해당 부분이 테스트되지 않기 때문에 나쁜 습관이 될 수 있다는 것을 알고 있습니다. 그러나 그것은 사실이 아닙니다. 저는 CI 테스트 서버 (jenkins)에서 전체 마이그레이션을 실행하고 있습니다. 속도가 중요한 로컬 테스트에서만 마이그레이션을 건너 뛰고 싶습니다.


일부 컨텍스트 :

Django 1.6 까지는 South를 사용할 때 SOUTH_TESTS_MIGRATE 설정을 사용했습니다 .

기본적으로 South의 syncdb 명령은 테스트를 실행할 때를 포함하여 비대화 형 모드에서 실행되는 경우 마이그레이션도 적용합니다. 테스트를 실행할 때마다 모든 마이그레이션이 실행됩니다.

테스트 실행기가 마이그레이션 대신 syncdb를 사용하도록하려면 (예 : 마이그레이션을 적용하는 데 너무 오래 걸리는 경우) settings.py에서 SOUTH_TESTS_MIGRATE = False를 설정하면됩니다.

그러나 syncdb 는 더 이상 존재하지 않으며 이제 migrate 입니다.

그리고 Django 1.8 에서 --keepdb 매개 변수를 사용합니다 .

--keepdb 옵션을 사용하여 테스트 실행 사이에 테스트 데이터베이스를 보존 할 수 있습니다. 이는 생성 및 삭제 작업을 모두 건너 뛰는 이점이있어 특히 대규모 테스트 스위트의 테스트 실행 시간을 크게 단축합니다. 테스트 데이터베이스가 존재하지 않는 경우 첫 번째 실행시 생성 된 다음 이후 실행될 때마다 보존됩니다. 적용되지 않은 마이그레이션은 테스트 스위트를 실행하기 전에 테스트 데이터베이스에도 적용됩니다.

따라서이 질문은 Django 1.7로 제한됩니다.


UT 동안에는 DB가 존재하지 않기 때문에 테스트하는 방식으로 마이그레이션을 실제로 실행하지 않는다고 주장합니다. 마이그레이션 테스트는 실제로 기존 DB를 마이그레이션 할 때만 발생합니다. 이 1.7 마이그레이션 사업은 제가 장고와 함께했던 안장 아래에있는 최초의 진짜 버어이지만, 정말 큰 자극입니다. South는 최소한 마이그레이션에 적합한 테스트 시나리오를 확보했습니다.
boatcoder 2014

django-test-without-migrations패키지는 당신이 허용 대답을 변경 할 수 있습니다, 나를 위해 정말 편리하고있다 stackoverflow.com/a/28993456/200224
앤디

가능하면 새로운 종속성을 추가하지 않는 것이 좋습니다.
David Arcos 2016

답변:


79

Bernie Sumption이 Django 개발자 메일 링리스트에 게시 한이 해결 방법을 살펴보십시오 .

makemigrations가 아직 실행되지 않은 경우 "migrate"명령은 앱을 마이그레이션되지 않은 것으로 처리하고 1.6에서 syncdb가 수행 한 것처럼 모델에서 직접 테이블을 만듭니다. 기본 설정 모듈에서 *를 가져오고 다음 줄을 추가하는 "settings_test.py"라는 단위 테스트를위한 새 설정 모듈을 정의했습니다.

MIGRATION_MODULES = { "myapp": "myapp.migrations_not_used_in_tests"}

그런 다음 다음과 같은 테스트를 실행합니다.

DJANGO_SETTINGS_MODULE = "myapp.settings_test"python manage.py 테스트

이 바보는 앱이 마이그레이션되지 않았다고 생각하게되므로 테스트 데이터베이스가 생성 될 때마다 models.py의 현재 구조를 반영합니다.

Django 1.9에서는이 상황 이 다소 개선 되었으며 값을 None다음 과 같이 설정할 수 있습니다 .

MIGRATION_MODULES = { "myapp": 없음}


9
이 참고 myapp.migrations_not_used_in_tests해야하지 존재하는 모듈.
bmihelac 2014 년

4
존재하지 않는 모듈에 대해 작성한 @bmihelac 주석 외에도 모듈 문자열에는 하위 문자열 'migrations'가 포함되어야합니다. 이유는 다음을 참조하십시오. github.com/django/django/blob/stable/1.7.x/django/db/migrations /…
nealtodd 2014 년

7
하십시오 settings_test.py 동적 MIGRATION_MODULES를 구축하는 기능의 요지 gist.github.com/nealtodd/2869341f38f5b1eeb86d
nealtodd

1
TY. 이 때문에 단위 테스트를 13 초에서 4 초로 줄일 수있었습니다. 또한 테스트를 위해 sqlite를 사용하면 더 많은 속도 향상을 찾을 수 있습니다. 나를 위해 테스트에 postgres를 사용하는 데 5.5 초가 걸리지 만 sqlite는 4 초가 걸립니다.
Gattster 2014

21
@nealtodd의 요점에 대한 의견에서 일부 함정을 피하고 매우 간단한 솔루션에 대한 링크가 있습니다. gist.github.com/NotSqrt/5f3c76cd15e40ef62d09
djsutho

72

내 설정 파일의 끝은 다음과 같습니다.

class DisableMigrations(object):

    def __contains__(self, item):
        return True

    def __getitem__(self, item):
        return None


TESTS_IN_PROGRESS = False
if 'test' in sys.argv[1:] or 'jenkins' in sys.argv[1:]:
    logging.disable(logging.CRITICAL)
    PASSWORD_HASHERS = (
        'django.contrib.auth.hashers.MD5PasswordHasher',
    )
    DEBUG = False
    TEMPLATE_DEBUG = False
    TESTS_IN_PROGRESS = True
    MIGRATION_MODULES = DisableMigrations()

스 니펫을 기반으로

테스트가 실행 중일 때만 마이그레이션을 비활성화했습니다.


1
좋은! __setitem__(self, *_)자체 마이그레이션을 설정하는 앱에 문제가 있었기 때문에 방법도 추가 하겠습니다. settings.MIGRATION_MODULES['chroniker'] = 'db_migrations'
Zhe Li

1
정말 감사합니다. 실제로 작동하는 유일한 방법입니다.
fluffels

병렬 모드에서 테스트를 실행할 때 Django 1.9에서 더 이상 작동하지 않습니다. 일반적인 비 병렬 테스트를 사용하면 계속 정상적으로 작동하지만 병렬 모드로 전환하면 테이블을 찾을 수 없다는 오류가 발생합니다.
LS55321

병렬 모드에서 @LeeSemel 당신은 아마 rlmv의 솔루션을 사용하려면
기욤 빈센트

@guillaumevincent 병렬 모드에서 django-test-without-migrations를 사용할 때 동일한 문제가 있습니다
LS55321


3

업데이트 : 신경 쓰지 마세요.이 변경 사항은 1.10 최종 버전이 출시되기 전에 되돌려졌습니다 . 바라건대 향후 버전에서 돌아올 것입니다.


Django 1.10부터는 테스트 데이터베이스 설정으로 제어 할 수 있습니다.

마이그레이션

기본: True

로 설정하면 FalseDjango는 마이그레이션을 사용하여 테스트 데이터베이스를 생성하지 않습니다.



1

django 1.9 이상에서는 Guillaume Vincent의 답변이 더 이상 작동하지 않으므로 여기에 새로운 솔루션이 있습니다.

내 설정 파일에서이 스 니펫을 사용하고 있습니다. INSTALLED_APPS

if os.environ.get('TESTS_WITHOUT_MIGRATIONS', False):
    MIGRATION_MODULES = {
        app.split('.')[-1]: None for app in INSTALLED_APPS
    }

설치된 모든 앱을 반복하고 각각 마이그레이션 모듈이없는 것으로 표시합니다. 자세한 내용은 django 문서를 참조하십시오 .

이 스 니펫을 사용하여 테스트를 실행하고 환경 변수를 설정할 수 있습니다 TESTS_WITHOUT_MIGRATIONS. 예 :

TESTS_WITHOUT_MIGRATIONS=1 ./manage.py test

1

나는 django 1.10 이후 마이그레이션을 비활성화하는 방법을 알아 냈습니다. 누군가에게 도움이 될 수 있습니다. 다음은 git의 링크입니다 .

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

    def __getitem__(self, item):
        return None

DATABASES = DisableMigrations()

MIGRATION_MODULES = DisableMigrations()

django 1.10 마이그레이션은 두 부분으로 구성됩니다. load_diskrecorder를 참조하십시오.

load_disk추가 된 앱의 마이그레이션 을 위한 INSTALL_APP 부분과 recorder데이터베이스 연결 을 위한 부분 1.9 이전 버전의 MIGRATION_MODULES={'do.not.migrate':'notmigrations'}경우 테스트를 실행할 때 설정해야합니다. 이제 설정해야합니다. None like MIGRATION_MODULES={'do.not.migrate':None} 그래서 우리가 어떤 앱에 대한 마이그레이션을 원하지 않는 경우 그냥 딕셔너리를 확장하고 반환 None을위한 getitem에서 동일한 기능, 그리고 어떻게 DATABASES당신이해야 할 옳은 일입니다,

추신 : 명령의 경우, 당신은 지정해야합니다 --setting=module.path.settings_test_snippettest PPS 당신이 작업하는 경우 pycharm, 하지 않는 설정 --settings 에서 옵션 Run/Debug configurations, 단지의 경로를 추가 settings_test_snippet.py사용자 설정에서. 괜찮아요 !!

즐겨

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.