web-dev-qa-db-fra.com

Désactiver les migrations lors de l'exécution de tests unitaires dans Django 1.7

Django 1.7 introduit migrations de bases de données .

Lors de l'exécution des tests unitaires dans Django 1.7, il force un migration, qui prend beaucoup de temps. Je souhaite donc ignorer les migrations Django et créer la base de données à l'état final.

Je sais qu'ignorer les migrations peut être une mauvaise pratique, car cette partie du code ne serait pas testée. Mais ce n'est pas le cas: j'exécute toutes les migrations sur le serveur de test CI (Jenkins). Je veux seulement ignorer les migrations dans mes tests locaux, où la vitesse compte.


Un peu de contexte:

Jusqu'à Django 1.6, en utilisant South, j'utilisais le paramètre SOUTH_TESTS_MIGRATE :

Par défaut, la commande syncdb de South appliquera également les migrations si elle est exécutée en mode non interactif, y compris lorsque vous exécutez des tests. Elle exécutera chaque migration à chaque fois que vous exécuterez vos tests.

Si vous voulez que le lanceur de tests utilise syncdb au lieu de migrer - par exemple, si vos migrations prennent trop de temps à s’appliquer - définissez simplement SOUTH_TESTS_MIGRATE = False dans settings.py.

Cependant, syncdb_ n'existe plus, maintenant il s'agit de migrate_.

Et à partir de Django 1.8, je vais utiliser le paramètre --keepdb:

L'option --keepdb peut être utilisée pour préserver la base de données de test entre les exécutions de test. Cela présente l’avantage d’ignorer les actions de création et de destruction, ce qui réduit considérablement le temps nécessaire pour exécuter des tests, en particulier ceux d’une grande suite de tests. Si la base de données test n'existe pas, elle sera créée lors de la première exécution, puis préservée pour chaque exécution suivante. Toutes les migrations non appliquées seront également appliquées à la base de données de test avant d'exécuter la suite de tests.

Donc, cette question est limitée à Django 1.7.

102
David Arcos

Regardez cette solution de contournement , postée par Bernie Sumption sur la liste de diffusion des développeurs de Django:

Si makemigrations n'a pas encore été exécuté, la commande "migrate" traite une application non migrée, et crée des tables directement à partir des modèles uniquement comme l'a fait syncdb en 1.6. J'ai défini un nouveau module de paramètres juste pour l'unité des tests appelés "settings_test.py", qui importe * du fichier principal module de paramètres et ajoute cette ligne:

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

Ensuite, je lance des tests comme celui-ci:

Django_SETTINGS_MODULE = "myapp.settings_test" test python manage.py

Ces imbéciles migrent en pensant que l'application n'est pas migrée, et ainsi chaque fois qu'une base de test est créée, elle reflète le fichier .__ actuel. structure de models.py.

Dans Django 1.9, cette situation est quelque peu améliorée , et vous pouvez définir la valeur sur None:

MIGRATION_MODULES = {"myapp": None}

75
albertgasset

Voici la fin de mon fichier de paramètres:

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

basé sur ceci extrait

J'ai désactivé les migrations uniquement lorsque les tests sont en cours d'exécution

68
Guillaume Vincent

Django-test-without-migrations ajoute un drapeau --nomigrations à manage.py test. Fonctionne comme un charme.

26
rlmv

Mise à jour: Peu importe, ce changement a été annulé avant la sortie de 1.10 final Espérons que cela reviendra dans une prochaine version.


Notez qu'à partir de Django 1.10, ceci peut être contrôlé par un paramètre de base de données de test.

ÉMIGRER

Valeur par défaut: True

Si défini sur False, Django n’utilisera pas les migrations pour créer la base de test.

https://Gist.github.com/apollovy/22826f493ad2d06d9a9a22464730ce0b

MIGRATION_MODULES = {
    app[app.rfind('.') + 1:]: 'my_app.migrations_not_used_in_tests'
    for app in INSTALLED_APPS
}
2
apollov

Pour Django 1.9 et supérieur, la réponse de Guillaume Vincent ne fonctionne plus, alors voici une nouvelle solution:

J'utilise cet extrait dans mon fichier de paramètres, après la définition du INSTALLED_APPS

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

Il effectue une itération sur toutes les applications installées et marque chacune d'elles comme dépourvues de module de migration. Voir la documentation Django pour plus d'informations .

À l'aide de cet extrait de code, vous pouvez exécuter vos tests en définissant la variable d'environnement TESTS_WITHOUT_MIGRATIONS, par exemple:

TESTS_WITHOUT_MIGRATIONS=1 ./manage.py test
1
devsnd

Je viens juste de comprendre comment désactiver les migrations après Django 1.10, cela pourrait peut-être aider quelqu'un. Voici link at git

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

    def __getitem__(self, item):
        return None

DATABASES = DisableMigrations()

MIGRATION_MODULES = DisableMigrations()

Migrations for Django 1.10 comporte deux parties. Veuillez consulter load_disk et recorder

La partie de load_disk pour le modèle de migration de l'application à ajouter à INSTALL_APP Et la partie de recorder pour la connexion à la base de données Pour la version antérieure à 1.9, il est nécessaire de définir MIGRATION_MODULES={'do.not.migrate':'notmigrations'} lorsque vous exécutez testNow, nous devons le définir MIGRATION_MODULES={'do.not.migrate':None} Donc, si nous ne voulons pas effectuer de migration pour une application, il suffit de prolonger un dict et de renvoyer None pour la fonction getitem, et de procéder de la même manière à DATABASES, c’est la bonne chose à faire.

PS: Pour la commande, vous devez spécifier --setting=module.path.settings_test_snippet après testPPS Si vous travaillez avec pycharm, ne définissez pas les options --settings sur Run/Debug configurations, ajoutez simplement le chemin d'accès de settings_test_snippet.py. à réglage personnalisé. Ça va bien !!

prendre plaisir

0
FavorMylikes