J'utilise un simple testeur basé sur un test unitaire pour tester mon application Django.
Mon application elle-même est configurée pour utiliser un enregistreur de base dans settings.py en utilisant:
logging.basicConfig(level=logging.DEBUG)
Et dans mon code d'application en utilisant:
logger = logging.getLogger(__name__)
logger.setLevel(getattr(settings, 'LOG_LEVEL', logging.DEBUG))
Cependant, lors de l'exécution de tests unitaires, j'aimerais désactiver la journalisation afin qu'elle n'encombre pas la sortie de mes résultats de test. Existe-t-il un moyen simple de désactiver la journalisation de manière globale, de sorte que les enregistreurs spécifiques à l'application n'écrivent pas de données sur la console lorsque j'exécute des tests?
python
django
unit-testing
logging
shreddd
la source
la source
Réponses:
désactivera tous les appels de journalisation avec des niveaux inférieurs ou égaux à
CRITICAL
. La journalisation peut être réactivée avecla source
logging.disable
(à partir de la réponse acceptée) en haut detests.py
votre application qui effectue la journalisation.tearDown()
méthode:logging.disable(logging.NOTSET)
remet la journalisation en place proprement.tests
module est très utile.Puisque vous êtes dans Django, vous pouvez ajouter ces lignes à votre settings.py:
De cette façon, vous n'avez pas à ajouter cette ligne dans tous
setUp()
vos tests.Vous pouvez également faire quelques modifications pratiques pour vos besoins de test de cette façon.
Il existe une autre façon "plus agréable" ou "plus propre" d'ajouter des détails à vos tests et c'est de créer votre propre testeur.
Créez simplement une classe comme celle-ci:
Et maintenant, ajoutez à votre fichier settings.py:
Cela vous permet de faire une modification vraiment pratique que l'autre approche ne fait pas, c'est-à-dire que Django teste simplement les applications que vous voulez. Vous pouvez le faire en modifiant l'
test_labels
ajout de cette ligne au testeur:la source
Les autres réponses empêchent «d'écrire des trucs sur la console» en configurant globalement l'infrastructure de journalisation pour qu'elle ignore quoi que ce soit. Cela fonctionne mais je trouve que c'est une approche trop directe. Mon approche consiste à effectuer un changement de configuration qui ne fait que ce qui est nécessaire pour empêcher les journaux de sortir sur la console. J'ajoute donc un filtre de journalisation personnalisé à mon
settings.py
:Et je configure la journalisation Django pour utiliser le filtre:
Résultat final: lorsque je teste, rien ne va à la console, mais tout le reste reste le même.
Pourquoi faire ceci?
Je conçois un code qui contient des instructions de journalisation qui ne sont déclenchées que dans des circonstances spécifiques et qui doivent générer les données exactes dont j'ai besoin pour le diagnostic en cas de problème. Par conséquent, je teste qu'ils font ce qu'ils sont censés faire et ainsi désactiver complètement la journalisation n'est pas viable pour moi. Je ne veux pas trouver une fois que le logiciel est en production que ce que je pensais être enregistré ne l'est pas.
De plus, certains testeurs (Nose, par exemple) captureront les journaux pendant les tests et afficheront la partie pertinente du journal avec un échec du test. Il est utile pour comprendre pourquoi un test a échoué. Si la journalisation est complètement désactivée, alors rien ne peut être capturé.
la source
test_settings.py
fichier qui se trouve à côté de celui de mon projetsettings.py
. Il est configuré pour se chargersettings.py
et apporter des modifications comme définiTESTING_MODE
surTrue
. Mes testeurs sont organisés de manière à ce quetest_settings
le module soit chargé pour les paramètres du projet Django. Cela peut être fait de plusieurs façons. Je vais généralement définir la variable d'environnementDJANGO_SETTINGS_MODULE
surproj.test_settings
.J'aime l'idée de testeur personnalisé de Hassek. Il convient de noter que ce
DjangoTestSuiteRunner
n'est plus le lanceur de test par défaut dans Django 1.6+, il a été remplacé par leDiscoverRunner
. Pour le comportement par défaut, le lanceur de test devrait ressembler davantage à:la source
helpers
, qui n'a que des utilitaires qui ne sont importés de nulle part ailleurs dans le projet.J'ai constaté que pour les tests dans
unittest
ou dans un cadre similaire, le moyen le plus efficace de désactiver en toute sécurité la journalisation indésirable dans les tests unitaires est d'activer / de désactiver les méthodessetUp
/tearDown
d'un cas de test particulier. Cela permet à une cible spécifiquement où les journaux doivent être désactivés. Vous pouvez également le faire explicitement sur le logger de la classe que vous testez.la source
J'utilise un décorateur de méthode simple pour désactiver la journalisation uniquement dans une méthode de test particulière.
Et puis je l'utilise comme dans l'exemple suivant:
la source
Il existe une méthode jolie et propre pour suspendre la connexion aux tests avec
unittest.mock.patch
method.foo.py :
tests.py :
Et
python3 -m unittest tests
ne produira aucune sortie de journalisation.la source
Parfois, vous voulez les journaux et parfois non. J'ai ce code dans mon
settings.py
Donc, si vous exécutez votre test avec les
--no-logs
options, vous n'obtiendrez que lescritical
journaux:C'est très utile si vous souhaitez accélérer les tests sur votre flux d'intégration continue.
la source
Si vous ne voulez pas l'activer / le désactiver à plusieurs reprises dans setUp () et tearDown () pour unittest (ne voyez pas la raison de cela), vous pouvez le faire une fois par classe:
la source
Dans les cas où je souhaite supprimer temporairement un enregistreur spécifique, j'ai écrit un petit gestionnaire de contexte que j'ai trouvé utile:
Vous l'utilisez ensuite comme:
Cela présente l'avantage que l'enregistreur est réactivé (ou remis à son état antérieur) une fois l'opération
with
terminée.la source
Vous pouvez le mettre dans le répertoire de niveau supérieur pour le
__init__.py
fichier de tests unitaires . Cela désactivera la journalisation globalement dans la suite de tests unitaires.la source
Dans mon cas, j'ai un fichier de paramètres
settings/test.py
créé spécifiquement à des fins de test, voici à quoi il ressemble:J'ai mis une variable d'environnement
DJANGO_SETTINGS_MODULE=settings.test
sur/etc/environment
.la source
Si vous avez différents modules d'initialisation pour le test, le développement et la production, vous pouvez désactiver n'importe quoi ou le rediriger dans l'initialser. J'ai local.py, test.py et production.py qui héritent tous de common.y
common.py fait toute la configuration principale, y compris cet extrait:
Ensuite, dans test.py j'ai ceci:
Cela remplace le gestionnaire de console par un FileHandler et signifie toujours obtenir la journalisation, mais je n'ai pas à toucher la base de code de production.
la source
Si vous utilisez
pytest
:Étant donné que pytest capture les messages du journal et ne les affiche que pour les tests ayant échoué, vous ne souhaitez généralement pas désactiver la journalisation. Au lieu de cela, utilisez un
settings.py
fichier séparé pour les tests (par exemple,test_settings.py
), et ajoutez-y:Cela indique à Django de ne pas configurer complètement la journalisation. Le
LOGGING
paramètre sera ignoré et peut être supprimé des paramètres.Avec cette approche, vous n'obtenez aucune journalisation pour les tests réussis et vous obtenez toute la journalisation disponible pour les tests ayant échoué.
Les tests seront exécutés à l'aide de la journalisation configurée par
pytest
. Il peut être configuré à votre guise dans lespytest
paramètres (par exemple,tox.ini
). Pour inclure les messages du journal de niveau de débogage, utilisezlog_level = DEBUG
(ou l'argument de ligne de commande correspondant).la source