EDIT : changement pour un meilleur exemple, et clarification de la raison pour laquelle c'est un vrai problème.
J'aimerais écrire des tests unitaires en Python qui continuent à s'exécuter lorsqu'une assertion échoue, afin de pouvoir voir plusieurs échecs dans un seul test. Par exemple :
class Car(object):
def __init__(self, make, model):
self.make = make
self.model = make # Copy and paste error: should be model.
self.has_seats = True
self.wheel_count = 3 # Typo: should be 4.
class CarTest(unittest.TestCase):
def test_init(self):
make = "Ford"
model = "Model T"
car = Car(make=make, model=model)
self.assertEqual(car.make, make)
self.assertEqual(car.model, model) # Failure!
self.assertTrue(car.has_seats)
self.assertEqual(car.wheel_count, 4) # Failure!
Ici, l'objectif du test est de s'assurer que Car's __init__
définit ses champs correctement. Je pourrais le décomposer en quatre méthodes (et c'est souvent une bonne idée), mais dans ce cas, je pense qu'il est plus lisible de le garder comme une seule méthode qui teste un seul concept ("l'objet est initialisé correctement").
Si nous supposons qu'il est préférable ici de ne pas fragmenter la méthode, j'ai alors un nouveau problème : je ne peux pas voir toutes les erreurs en même temps. Lorsque je corrige la model
et ré-exécuter le test, alors l'option wheel_count
erreur apparaît. Cela me ferait gagner du temps de voir les deux erreurs lorsque je lance le test pour la première fois.
À titre de comparaison, le cadre de test unitaire C++ de Google fait la distinction entre entre les cas non mortels EXPECT_*
assertions et fatalité ASSERT_*
les assertions :
Les assertions sont présentées par paires et testent la même chose mais ont des effets différents sur la fonction courante. Les versions ASSERT_* génèrent des échecs fatals lorsqu'elles échouent, et interrompent la fonction courante. Les versions EXPECT_* génèrent des échecs non fatals, qui n'interrompent pas la fonction courante. En général, les versions EXPECT_* sont préférées, car elles permettent de signaler plusieurs échecs dans un test. Cependant, vous devriez utiliser ASSERT_* si cela n'a pas de sens de continuer lorsque l'assertion en question échoue.
Y a-t-il un moyen d'obtenir EXPECT_*
-dans le langage Python unittest
? Si ce n'est pas le cas unittest
Dans ce cas, existe-t-il un autre cadre de test unitaire Python qui supporte ce comportement ?
Par ailleurs, j'étais curieux de savoir combien de tests réels pouvaient bénéficier d'assertions non fatales. exemples de code (édité le 2014-08-19 pour utiliser searchcode au lieu de Google Code Search, RIP). Sur 10 résultats choisis au hasard sur la première page, tous contenaient des tests qui faisaient plusieurs assertions indépendantes dans la même méthode de test. Tous bénéficieraient d'assertions non fatales.
2 votes
Qu'avez-vous fini par faire ? Je suis intéressé par ce sujet (pour des raisons complètement différentes dont je serais heureux de discuter dans un endroit plus spacieux qu'un commentaire) et j'aimerais connaître votre expérience. Au fait, le lien "exemples de code" se termine par "Sadly, this service has been shut down", donc si vous avez une version cachée de ce lien, je serais intéressé de la voir aussi.
0 votes
Pour une référence future, je crois este est la recherche équivalente sur le système actuel, mais les résultats ne sont plus ceux décrits ci-dessus.
2 votes
@Davide, je n'ai pas fini de faire quelque chose. L'approche "une seule assertion par méthode" me semble trop rigide et dogmatique, mais la seule solution viable (et maintenable) semble être la suggestion "catch and append" d'Anthony. C'est trop laid pour moi, cependant, donc je me suis contenté de plusieurs assertions par méthode, et je devrai vivre avec des tests exécutés plus de fois que nécessaire pour trouver toutes les défaillances.
0 votes
Le cadre de test python appelé PyTest est assez intuitif, et montre par défaut tous les échecs d'assertion. Cela pourrait être une solution au problème que vous rencontrez.