Si j'écris des tests unitaires en python (en utilisant le module unittest), est-il possible de sortir des données d'un test ayant échoué, afin que je puisse l'examiner pour aider à déduire la cause de l'erreur? Je suis conscient de la possibilité de créer un message personnalisé, qui peut contenir des informations, mais parfois vous pouvez traiter des données plus complexes, qui ne peuvent pas être facilement représentées sous forme de chaîne.
Par exemple, supposons que vous ayez une classe Foo et que vous testiez une barre de méthodes, en utilisant les données d'une liste appelée testdata:
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
Si le test a échoué, je pourrais vouloir sortir t1, t2 et / ou f, pour voir pourquoi ces données particulières ont entraîné un échec. Par sortie, je veux dire que les variables sont accessibles comme toutes les autres variables, une fois le test exécuté.
la source
msg
est utilisé, il remplacera le message d'erreur normal. Pour êtremsg
ajouté au message d'erreur normal, vous devez également définir TestCase.longMessage sur TrueTrue
.Nous utilisons le module de journalisation pour cela.
Par exemple:
Cela nous permet d'activer le débogage pour des tests spécifiques dont nous savons qu'ils échouent et pour lesquels nous voulons des informations de débogage supplémentaires.
Ma méthode préférée, cependant, n'est pas de passer beaucoup de temps sur le débogage, mais de le passer à écrire des tests plus fins pour exposer le problème.
la source
foo
? Une fonction distincte? Une méthode fonction deSomeTest
? Dans le premier cas, une fonction peut avoir son propre enregistreur. Dans le second cas, l'autre fonction de méthode peut avoir son propre enregistreur. Connaissez-vous le fonctionnement dulogging
package? Plusieurs enregistreurs sont la norme.Vous pouvez utiliser des instructions d'impression simples ou tout autre moyen d'écrire dans stdout. Vous pouvez également appeler le débogueur Python n'importe où dans vos tests.
Si vous utilisez nose pour exécuter vos tests (ce que je recommande), il collectera le stdout pour chaque test et ne vous le montrera que si le test a échoué, vous n'avez donc pas à vivre avec la sortie encombrée lorsque les tests réussissent.
nose a également des commutateurs pour afficher automatiquement les variables mentionnées dans les assertions ou pour invoquer le débogueur en cas d'échec des tests. Par exemple
-s
(--nocapture
) empêche la capture de stdout.la source
print
etlog.debug()
l'un à côté de l'autre, et j'active explicitement laDEBUG
journalisation à la racine de lasetUp()
méthode, mais seule laprint
sortie apparaît.nosetests -s
montre le contenu de stdout s'il y a une erreur ou non - quelque chose que je trouve utile.Je ne pense pas que ce soit tout à fait ce que vous recherchez, il n'y a aucun moyen d'afficher des valeurs de variable qui n'échouent pas, mais cela peut vous aider à vous rapprocher de la sortie des résultats comme vous le souhaitez.
Vous pouvez utiliser l' objet TestResult renvoyé par TestRunner.run () pour l'analyse et le traitement des résultats. En particulier, TestResult.errors et TestResult.failures
À propos de l'objet TestResults:
http://docs.python.org/library/unittest.html#id3
Et du code pour vous orienter dans la bonne direction:
la source
Une autre option - démarrer un débogueur là où le test échoue.
Essayez d'exécuter vos tests avec Testoob (il exécutera votre suite unittest sans modifications), et vous pouvez utiliser le commutateur de ligne de commande '--debug' pour ouvrir un débogueur lorsqu'un test échoue.
Voici une session de terminal sur Windows:
la source
La méthode que j'utilise est vraiment simple. Je l'enregistre simplement comme un avertissement pour qu'il apparaisse réellement.
la source
Je pense que j'y ai peut-être trop réfléchi. Une façon dont je suis venu avec qui fait le travail, est simplement d'avoir une variable globale, qui accumule les données de diagnostic.
Quelque chose comme ça:
Merci pour les réponses. Ils m'ont donné des idées alternatives sur la façon d'enregistrer des informations à partir de tests unitaires en python.
la source
Utilisez la journalisation:
Usage:
Si vous ne définissez pas
LOG_FILE
, la journalisation sera effectuéestderr
.la source
Vous pouvez utiliser le
logging
module pour cela.Donc, dans le code de test unitaire, utilisez:
Par défaut, les avertissements et les erreurs sont envoyés vers
/dev/stderr
, ils doivent donc être visibles sur la console.Pour personnaliser les journaux (tels que la mise en forme), essayez l'exemple suivant:
la source
Ce que je fais dans ces cas est d'avoir un
log.debug()
avec quelques messages dans mon application. Étant donné que le niveau de journalisation par défaut estWARNING
, ces messages ne s'affichent pas dans l'exécution normale.Ensuite, dans le test unittest, je change le niveau de journalisation en
DEBUG
, afin que ces messages soient affichés lors de leur exécution.Dans les unittests:
Voir un exemple complet:
Il s'agit d'
daikiri.py
une classe de base qui implémente un Daikiri avec son nom et son prix. Il existe une méthodemake_discount()
qui renvoie le prix de ce daikiri spécifique après avoir appliqué une remise donnée:Ensuite, je crée un unittest
test_daikiri.py
qui vérifie son utilisation:Donc, quand je l'exécute, je reçois les
log.debug
messages:la source
inspect.trace vous permettra d'obtenir des variables locales après qu'une exception a été levée. Vous pouvez ensuite envelopper les tests unitaires avec un décorateur comme le suivant pour enregistrer ces variables locales pour examen lors de l'autopsie.
La dernière ligne affichera les valeurs renvoyées là où le test a réussi et les variables locales, dans ce cas x, en cas d'échec:
Har det gøy :-)
la source
Que diriez-vous d'attraper l'exception qui est générée à partir de l'échec d'assertion? Dans votre bloc catch, vous pouvez sortir les données comme vous le souhaitez, où que vous soyez. Ensuite, lorsque vous avez terminé, vous pouvez relancer l'exception. Le testeur ne connaîtrait probablement pas la différence.
Avertissement: Je n'ai pas essayé cela avec le framework de test unitaire de python, mais avec d'autres frameworks de test unitaire.
la source
En admettant que je ne l'ai pas essayé, la fonction de journalisation de testfixtures semble assez utile ...
la source
En élargissant la réponse de @FC, cela fonctionne très bien pour moi:
la source