Je veux écrire un test pour établir qu'une exception n'est pas déclenchée dans une circonstance donnée.
Il est facile de vérifier si une exception est est soulevée ...
sInvalidPath=AlwaysSuppliesAnInvalidPath()
self.assertRaises(PathIsNotAValidOne, MyObject, sInvalidPath)
... mais comment pouvez-vous faire le opposé .
Quelque chose comme ça c'est ce que je cherche ...
sValidPath=AlwaysSuppliesAValidPath()
self.assertNotRaises(PathIsNotAValidOne, MyObject, sValidPath)
def run_test(self):
try:
myFunc()
except ExceptionType:
self.fail("myFunc() raised ExceptionType unexpectedly!")
Bonjour - Je souhaite rédiger un test pour établir qu’une exception n’est pas déclenchée dans une situation donnée.
C'est l'hypothèse par défaut - les exceptions ne sont pas levées.
Si vous ne dites rien d'autre, c'est supposé dans chaque test.
Vous n'êtes pas obligé d'écrire une affirmation pour cela.
Appelez simplement la fonction. S'il soulève une exception, le cadre de test unitaire le signalera comme une erreur. Vous voudrez peut-être ajouter un commentaire, par exemple:
sValidPath=AlwaysSuppliesAValidPath()
# Check PathIsNotAValidOne not thrown
MyObject(sValidPath)
Je suis l’affiche originale et j’ai accepté la réponse ci-dessus de la part de DGH sans l’avoir utilisée au préalable dans le code.
Une fois que j’ai utilisé, j’ai réalisé qu’il fallait faire quelques ajustements pour faire ce que j’avais besoin de faire (pour être juste envers DGH, il/elle a effectivement dit "ou quelque chose de similaire"!).
Je pensais que ça valait la peine de poster le Tweak ici pour le bénéfice des autres:
try:
a = Application("abcdef", "")
except pySourceAidExceptions.PathIsNotAValidOne:
pass
except:
self.assertTrue(False)
Ce que j’essayais de faire ici était de faire en sorte que si on tentait d’instancier un objet Application avec un deuxième argument d’espaces, on déclenche la pySourceAidExceptions.PathIsNotAValidOne.
Je crois que l'utilisation du code ci-dessus (basé fortement sur la réponse de DGH) le fera.
Vous pouvez définir assertNotRaises
en réutilisant environ 90% de l'implémentation originale de assertRaises
dans le module unittest
. Avec cette approche, vous vous retrouvez avec une méthode assertNotRaises
qui, outre sa condition d'échec inversé, se comporte de manière identique à assertRaises
.
Il s'avère étonnamment facile d'ajouter une méthode assertNotRaises
à unittest.TestCase
(il m'a fallu environ quatre fois plus de temps pour écrire cette réponse que pour le code). Voici une démonstration en direct de la méthode assertNotRaises
en action . Juste comme assertRaises
, vous pouvez soit passer un callable et argumenter à assertNotRaises
, ou vous pouvez l’utiliser dans une instruction with
. La démonstration en direct inclut un scénario de test démontrant que assertNotRaises
fonctionne comme prévu.
L'implémentation de assertRaises
dans unittest
est assez compliquée, mais avec un peu de sous-classement astucieux, vous pouvez remplacer et inverser sa condition d'échec.
assertRaises
est une méthode courte qui crée simplement une instance de la classe unittest.case._AssertRaisesContext
et la renvoie (voir sa définition dans le module unittest.case
). Vous pouvez définir votre propre classe _AssertNotRaisesContext
en sous-classant _AssertRaisesContext
et en remplaçant sa méthode __exit__
:
import traceback
from unittest.case import _AssertRaisesContext
class _AssertNotRaisesContext(_AssertRaisesContext):
def __exit__(self, exc_type, exc_value, tb):
if exc_type is not None:
self.exception = exc_value.with_traceback(None)
try:
exc_name = self.expected.__name__
except AttributeError:
exc_name = str(self.expected)
if self.obj_name:
self._raiseFailure("{} raised by {}".format(exc_name,
self.obj_name))
else:
self._raiseFailure("{} raised".format(exc_name))
else:
traceback.clear_frames(tb)
return True
Normalement, vous définissez les classes de cas de test en les faisant hériter de TestCase
. Si vous héritez d'une sous-classe MyTestCase
:
class MyTestCase(unittest.TestCase):
def assertNotRaises(self, expected_exception, *args, **kwargs):
context = _AssertNotRaisesContext(expected_exception, self)
try:
return context.handle('assertNotRaises', args, kwargs)
finally:
context = None
la méthode assertNotRaises
sera désormais disponible dans tous vos scénarios de test.
Si vous transmettez une classe d'exception à assertRaises()
, un gestionnaire de contexte est fourni. Cela peut améliorer la lisibilité de vos tests:
# raise exception if Application created with bad data
with self.assertRaises(pySourceAidExceptions.PathIsNotAValidOne):
application = Application("abcdef", "")
Cela vous permet de tester les cas d'erreur dans votre code.
Dans ce cas, vous testez la PathIsNotAValidOne
est déclenchée lorsque vous transmettez des paramètres non valides au constructeur de l'application.
J'ai trouvé utile de corriger la variable unittest
comme suit:
def assertMayRaise(self, exception, expr):
if exception is None:
try:
expr()
except:
info = sys.exc_info()
self.fail('%s raised' % repr(info[0]))
else:
self.assertRaises(exception, expr)
unittest.TestCase.assertMayRaise = assertMayRaise
Ceci clarifie l’intention lors du test d’absence d’exception:
self.assertMayRaise(None, does_not_raise)
Cela simplifie également les tests en boucle, ce que je me trouve souvent à faire:
# ValueError is raised only for op(x,x), op(y,y) and op(z,z).
for i,(a,b) in enumerate(itertools.product([x,y,z], [x,y,z])):
self.assertMayRaise(None if i%4 else ValueError, lambda: op(a, b))
def _assertNotRaises(self, exception, obj, attr):
try:
result = getattr(obj, attr)
if hasattr(result, '__call__'):
result()
except Exception as e:
if isinstance(e, exception):
raise AssertionError('{}.{} raises {}.'.format(obj, attr, exception))
pourrait être modifié si vous devez accepter des paramètres.
appeler comme
self._assertNotRaises(IndexError, array, 'sort')
vous pouvez essayer comme ça. essayer: self.assertRaises (Aucun, fonction, arg1, arg2) sauf: pass si vous ne mettez pas de code dans try à un bloc, il passera à l'exception de 'AssertionError: aucun non levé "et le test sera échoué.