84 votes

Comment tester avec le test unitaire de Python qu'un avertissement a été lancé ?

J'ai une fonction suivante en Python et je veux tester avec unittest que si la fonction obtient 0 comme argument, elle lance un avertissement. J'ai déjà essayé assertRaises, mais comme je ne déclenche pas l'avertissement, cela ne fonctionne pas.

 def isZero(i):
    if i != 0:
        print "OK"
    else:
        warning = Warning("the input is 0!") 
        print warning
    return i

89voto

Melebius Points 529

À partir de Python 3.2, vous pouvez simplement utiliser la méthode assertWarns()

 with self.assertWarns(Warning):
    do_something()

61voto

ire_and_curses Points 32802

Vous pouvez utiliser le gestionnaire de contexte catch_warnings Essentiellement, cela vous permet de vous moquer du gestionnaire d'avertissements, afin que vous puissiez vérifier les détails de l'avertissement. Voir les documents officiels pour une explication plus complète et un exemple de code de test.

 import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")
    # Trigger a warning.
    fxn()
    # Verify some things
    assert len(w) == 1
    assert issubclass(w[-1].category, DeprecationWarning)
    assert "deprecated" in str(w[-1].message)

18voto

Altaisoft Points 461

Vous pouvez écrire votre propre fonction assertWarns pour encapsuler le contexte catch_warnings. Je viens de l'implémenter de la manière suivante, avec un mixin :

 class WarningTestMixin(object):
    'A test which checks if the specified warning was raised'

    def assertWarns(self, warning, callable, *args, **kwds):
        with warnings.catch_warnings(record=True) as warning_list:
            warnings.simplefilter('always')

            result = callable(*args, **kwds)

            self.assertTrue(any(item.category == warning for item in warning_list))

Un exemple d'utilisation :

 class SomeTest(WarningTestMixin, TestCase):
    'Your testcase'

    def test_something(self):
        self.assertWarns(
            UserWarning,
            your_function_which_issues_a_warning,
            5, 10, 'john', # args
            foo='bar'      # kwargs
        )

Le test réussira si au moins un des avertissements émis par your_function est de type UserWarning.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X