Django 1.7'de birim testleri çalıştırırken geçişleri devre dışı bırakın


110

Django 1.7 , veritabanı geçişlerini tanıttı .

Django 1.7'de birim testlerini çalıştırırken, uzun zaman alan bir geçişi zorlar . Bu yüzden django geçişlerini atlamak ve veritabanını son durumda oluşturmak istiyorum.

Kodun bu kısmı test edilmeyeceği için geçişleri görmezden gelmenin kötü bir uygulama olabileceğini biliyorum. Ancak durum bu değil: CI test sunucusunda (jenkins) tam geçişleri çalıştırıyorum. Sadece hızın önemli olduğu yerel testlerimde geçişleri atlamak istiyorum.


Bazı bağlam:

Django kadar 1.6 Güney kullanırken, kullandığım SOUTH_TESTS_MIGRATE ayarı:

Varsayılan olarak, South'un syncdb komutu, etkileşimli olmayan modda çalıştırılırsa, testleri çalıştırdığınızda da dahil olmak üzere geçişleri uygular - testlerinizi her çalıştırdığınızda her geçişi çalıştırır.

Test çalıştırıcısının taşıma yerine syncdb kullanmasını istiyorsanız - örneğin, geçişleriniz çok uzun sürüyorsa - settings.py içinde SOUTH_TESTS_MIGRATE = False ayarını yapmanız yeterlidir.

Ancak syncdb artık mevcut değil, şimdi göç ediyor .

Ve Django 1.8'den --keepdb parametresini kullanacağım :

--Keepdb seçeneği, test çalıştırmaları arasında test veritabanını korumak için kullanılabilir. Bu, hem oluşturma hem de yok etme eylemlerini atlama avantajına sahiptir ve bu da, özellikle büyük bir test paketindekiler olmak üzere testleri çalıştırma süresini büyük ölçüde azaltır. Test veritabanı yoksa, ilk çalıştırmada oluşturulur ve ardından sonraki her çalıştırmada korunur. Uygulanmayan geçişler, test paketini çalıştırmadan önce test veritabanına da uygulanacaktır.

Yani bu soru Django 1.7 ile sınırlıdır.


UT sırasında, başladığınız DB mevcut olmadığından, geçişleri gerçekten onları test edecek şekilde çalıştırmadığınızı iddia ediyorum. Geçişlerin test edilmesi gerçekten yalnızca mevcut bir DB'yi geçirirken gerçekleşir. Bu 1.7 göç işi, Django ile yaşadığım eyerin altındaki ilk gerçek çapak, ama bu gerçekten çok rahatsız edici. Güney en azından göçler için test senaryosunu doğru aldı.
boatcoder

django-test-without-migrationsPaket için kabul edilen cevabını değiştirmek isteyebilirsiniz, benim için gerçekten kullanışlı olmuştur stackoverflow.com/a/28993456/200224
Andy

Mümkünse yeni bağımlılıklar eklemekten kaçınmayı tercih ederim.
David Arcos

Yanıtlar:


79

Bak bu geçici çözüm Django geliştiricileri posta listesine Bernie büyük öncül tarafından gönderildi:

Makemigrations henüz çalıştırılmadıysa, "migrate" komutu bir uygulamayı taşınmamış olarak değerlendirir ve syncdb 1.6'da yaptığı gibi doğrudan modellerden tablolar oluşturur. Sadece "settings_test.py" adlı birim testleri için, ana ayarlar modülünden * içe aktaran ve şu satırı ekleyen yeni bir ayarlar modülü tanımladım:

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

Sonra şöyle testler yapıyorum:

DJANGO_SETTINGS_MODULE = "myapp.settings_test" python manage.py testi

Bu aptallar, uygulamanın taşınmamış olduğunu düşünmeye başlarlar ve bu nedenle, bir test veritabanı her oluşturulduğunda, models.py'nin mevcut yapısını yansıtır.

Django 1.9'da bu durum bir şekilde iyileştirilmiştir ve değeri şu şekilde ayarlayabilirsiniz None:

MIGRATION_MODULES = {"uygulamam": Yok}


9
Not myapp.migrations_not_used_in_testsshould not var modülü.
bmihelac

4
Mevcut olmayan modül hakkında yapılan @bmihelac yoruma ek olarak, modül dizesi 'geçişler' alt dizesini içermelidir, Neden bakın: github.com/django/django/blob/stable/1.7.x/django/db/migrations /…
nealtodd

7
Settings_test.py'de dinamik olarak MIGRATION_MODULES oluşturmak için bir işlevin özeti: gist.github.com/nealtodd/2869341f38f5b1eeb86d
nealtodd

1
TY. Bu sayede birim testlerimi 13 saniyeden 4 saniyeye indirebildim. Ayrıca, test için sqlite kullanarak daha fazla hız kazanımı elde edilebilir. Benim için testler için postgres kullanmak 5,5 saniye, sqlite 4 saniye sürüyor.
Gattster

21
@ Nealtodd'nin özündeki yorumlardan, bazı tuzaklardan kaçınan ve süper basit olan bir çözüme bağlantı aşağıda verilmiştir: gist.github.com/NotSqrt/5f3c76cd15e40ef62d09
djsutho

72

Ayarlar dosyamın sonu:

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()

bu parçacığa göre

Taşıma işlemlerini yalnızca testler çalışırken devre dışı bıraktım


1
Güzel! __setitem__(self, *_)Yöntem de ekleyecektim çünkü kendi geçişlerini ayarlayan uygulamalarda sorun yaşıyorduk settings.MIGRATION_MODULES['chroniker'] = 'db_migrations'
Zhe Li

1
Bunun için çok teşekkür ederim, işe yaradığını bulduğum tek şey bu.
2016

Bu, testleri paralel modda çalıştırırken artık Django 1.9'da çalışmıyor. Normal paralel olmayan testi kullanarak düzgün çalışmaya devam eder, ancak paralel moda geçmek, tabloların bulunamaması gibi hatalara neden olur.
LS55321

@LeeSemel paralel modda muhtemelen rlmv'den çözümü kullanmak istiyorsunuz
Guillaume Vincent

@guillaumevincent paralel modda django-test-migration olmadan kullanırken de aynı sorunu
yaşıyorum


3

Güncelleme : Boş ver, bu değişiklik 1.10 final yayınlanmadan önce geri alındı. Umarım gelecekteki bir sürümde geri dönecektir.


Django 1.10'dan itibaren bunun bir test veritabanı ayarı ile kontrol edilebileceğini unutmayın.

GÖÇ

Varsayılan: True

Olarak ayarlanırsa False, Django test veritabanını oluşturmak için geçişleri kullanmaz.



1

Django 1.9 ve üstü için Guillaume Vincent'ın cevabı artık işe yaramıyor, işte yeni bir çözüm:

Bu pasajı ayarlar dosyamda, tanımından sonra kullanıyorum INSTALLED_APPS

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

Yüklü tüm uygulamaları yineler ve her birini geçiş modülü yok olarak işaretler. Daha fazla bilgi için django belgelerine bakın .

Bu parçacığı kullanarak, ortam değişkenini ayarlayarak testlerinizi çalıştırabilirsiniz TESTS_WITHOUT_MIGRATIONS, örneğin:

TESTS_WITHOUT_MIGRATIONS=1 ./manage.py test

1

Sadece django 1.10'dan sonra geçişleri nasıl devre dışı bırakacağımı buldum, birileri için yardımcı olabilir. İşte bağlantı Git de

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

    def __getitem__(self, item):
        return None

DATABASES = DisableMigrations()

MIGRATION_MODULES = DisableMigrations()

Django 1.10 için geçişlerin iki kısmı vardır, lütfen load_disk ve kaydediciye bakın

load_diskUygulamanın geçiş modelinin bölümüne Eklenecek INSTALL_APP kısmı Ve recorderveritabanı bağlantısı için olan kısmı 1.9'dan önceki sürüm MIGRATION_MODULES={'do.not.migrate':'notmigrations'}için testi çalıştırırken ayarlamamız gerekiyor Şimdi bunu ayarlamamız gerekiyor Hiçbiri MIGRATION_MODULES={'do.not.migrate':None} Öyle herhangi bir uygulama için geçiş yapmak istemiyorsak , sadece bir karar verin ve işlev Noneiçin geri dönün getitemve aynı DATABASESşeyi yapın, yapmanız gereken doğru şey budur

Not: Komut için, PPS'den--setting=module.path.settings_test_snippet sonra belirtmeniz gerekir.Eğer ile çalışıyorsanız , ' da seçenekleri ayarlamayın , sadece yol ekleyintest pycharm--settingsRun/Debug configurationssettings_test_snippet.py , Özel ayarına . Bu iyi olur !!

zevk almak

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.