Mes tests unitaires Django prennent beaucoup de temps à s'exécuter, je cherche donc des moyens d'accélérer cela. J'envisage d'installer un SSD , mais je sais que cela a aussi ses inconvénients. Bien sûr, il y a des choses que je pourrais faire avec mon code, mais je recherche une solution structurelle. Même l'exécution d'un seul test est lente car la base de données doit être reconstruite / migrée vers le sud à chaque fois. Alors voici mon idée ...
Puisque je sais que la base de données de test sera toujours assez petite, pourquoi ne puis-je pas simplement configurer le système pour toujours garder toute la base de données de test dans la RAM? Ne touchez jamais du tout au disque. Comment configurer cela dans Django? Je préférerais continuer à utiliser MySQL car c'est ce que j'utilise en production, mais si SQLite 3 ou autre chose rend cela facile, j'irais dans cette direction.
SQLite ou MySQL a-t-il une option pour s'exécuter entièrement en mémoire? Il devrait être possible de configurer un disque RAM, puis de configurer la base de données de test pour y stocker ses données, mais je ne sais pas comment dire à Django / MySQL d'utiliser un répertoire de données différent pour une certaine base de données, d'autant plus qu'elle ne cesse de s'effacer et recréé chaque essai. (Je suis sur un Mac FWIW.)
la source
"test" in sys.argv
; il peut se déclencher lorsque vous ne le souhaitez pas, par exemplemanage.py collectstatic -i test
.sys.argv[1] == "test"
est une condition plus précise qui ne devrait pas avoir ce problème.Je crée généralement un fichier de paramètres séparé pour les tests et je l'utilise dans la commande de test, par exemple
Il présente deux avantages:
Vous n'avez pas à vérifier
test
ou un tel mot magique dans sys.argv,test_settings.py
peut simplement êtreVous pouvez également l'ajuster davantage à vos besoins, en séparant proprement les paramètres de test des paramètres de production.
Un autre avantage est que vous pouvez exécuter des tests avec le moteur de base de données de production au lieu de sqlite3 en évitant les bogues subtils, donc lors du développement de l'utilisation
et avant de valider le code, exécutez une fois
juste pour être sûr que tous les tests réussissent vraiment.
la source
MySQL prend en charge un moteur de stockage appelé "MEMORY", que vous pouvez configurer dans votre base de données config (
settings.py
) comme tel:Notez que le moteur de stockage MEMORY ne prend pas en charge les colonnes blob / texte, donc si vous l'utilisez,
django.db.models.TextField
cela ne fonctionnera pas pour vous.la source
Je ne peux pas répondre à votre question principale, mais il y a plusieurs choses que vous pouvez faire pour accélérer les choses.
Tout d'abord, assurez-vous que votre base de données MySQL est configurée pour utiliser InnoDB. Ensuite, il peut utiliser des transactions pour restaurer l'état de la base de données avant chaque test, ce qui, selon mon expérience, a conduit à une accélération massive. Vous pouvez passer une commande d'initialisation de la base de données dans votre settings.py (syntaxe Django 1.2):
Deuxièmement, vous n'avez pas besoin d'exécuter les migrations Sud à chaque fois. Définissez
SOUTH_TESTS_MIGRATE = False
dans votre settings.py et la base de données sera créée avec syncdb simple, ce qui sera beaucoup plus rapide que d'exécuter toutes les migrations historiques.la source
369 tests in 498.704s
à369 tests in 41.334s
. C'est plus de 10 fois plus rapide!--keep
pour conserver la base de données et ne pas exiger que votre ensemble complet de migrations soit réappliqué à chaque exécution de test. Les nouvelles migrations continueront de fonctionner. Si vous passez fréquemment d'une branche à l'autre, il est cependant facile d'entrer dans un état incohérent (vous pouvez annuler les nouvelles migrations avant de passer en changeant la base de données vers la base de données de test et en l'exécutantmigrate
, mais c'est un peu pénible).Vous pouvez faire un double ajustement:
J'utilise les deux trucs et je suis plutôt content.
Comment le configurer pour MySQL sur Ubuntu:
Attention, c'est juste pour le test, après le redémarrage de votre base de données depuis la mémoire est perdue!
la source
Une autre approche: avoir une autre instance de MySQL exécutée dans un tempfs qui utilise un disque RAM. Instructions dans ce billet de blog: Accélérer MySQL pour les tests dans Django .
Avantages:
la source
En prolongeant la réponse d'Anurag, j'ai simplifié le processus en créant les mêmes test_settings et en ajoutant ce qui suit à manage.py
semble plus propre puisque sys est déjà importé et manage.py n'est utilisé que via la ligne de commande, donc pas besoin d'encombrer les paramètres
la source
"test" in sys.argv
; il peut se déclencher lorsque vous ne le souhaitez pas, par exemplemanage.py collectstatic -i test
.sys.argv[1] == "test"
est une condition plus précise qui ne devrait pas avoir ce problème../manage.py
sans arguments (par exemple pour voir quels plugins sont disponibles, comme--help
)len(sys.argv) > 1 and sys.argv[1] == "test"
Utilisez ci-dessous dans votre
setting.py
la source