12
votes

Utilisation d'un gestionnaire de contexte avec Python Assertraises

La documentation Python pour Unitest implique que la méthode Assertraises () peut être utilisée comme gestionnaire de contexte. Le code ci-dessous montre en donne un exemple simple des unitTest des Documents Python. Le Assertraises () L'appel dans la méthode testsample () fonctionne bien.

Maintenant, j'aimerais accéder à l'exception lorsqu'il est soulevé, mais si je le commente et que je le décompte le prochain bloc dans lequel je tente d'utiliser un gestionnaire de contexte, je reçois un attributeError: __exit __ lorsque j'essaie d'exécuter le code. Cela se produit pour les deux python 2.7.2 et 3.2.2. Je pourrais attraper l'exception dans un essayer ... sauf bloquer et y accéder à cette façon, mais la documentation de l'unit semble impliquer que le gestionnaire de contexte le ferait également.

est Il y a autre chose d'autre que je fais mal ici? xxx


0 commentaires

4 Réponses :


3
votes

Selon la documentation:

Si appelé avec CallableBj omis ou aucun, retournera un objet de contexte

de sorte que le code devrait être: xxx


1 commentaires

Si je comprends bien la question de l'OP correctement, il semble qu'il veut intercepter l'exception et faire un travail supplémentaire avec celui-ci (affirmant éventuellement le message sous-jacent ou quelque tel), donc je ne pense pas que cette réponse aide.



7
votes

Le code source pour unitest ne 'T Affiche un crochet d'exception pour Assertraises em>: xxx pré>

Donc, comme vous le soupçonnez, former votre propre try / sauf Bloquer est la voie à suivre si vous voulez intercepter si vous souhaitez intercepter si vous souhaitez intercepter si vous souhaitez intercepter. L'exception tout en conservant toujours le test d'Assertraises: P>

def testsample(self):
    with self.assertRaises(ValueError):
         try:
             random.sample(self.seq, 20)
         except ValueError as e:
             # do some action with e
             self.assertEqual(e.args,
                              ('sample larger than population',))
             # now let the context manager do its work
             raise                    


3 commentaires

Merci, cela fonctionne, mais il semble que ceci soit à l'envers de la manière dont la documentation le décrit à moins que je ne le lis pas mal. Cela ne semble pas vraiment que vous auriez besoin du gestionnaire de contexte dans le code corrigé de R Hettinger. Que gagnez-vous du gestionnaire de contexte? Vous avez déjà attrapé l'exception pour les tests. Si l'exception n'a pas eu lieu, vous pouvez toujours signaler cela dans d'autres clauses liées à la clause d'exception.


@Pauljoireman: Oui, vous pourriez le faire sans assertaises si vous préférez. Le gestionnaire de contexte fait simplement le cas simple (vérifier qu'une exception particulière est soulevée) plus facile à lire.


Pouvez-vous s'il vous plaît aidez-moi dans une question connexe? Stackoverflow.com/Questtions/39909935/...



26
votes

Il semble que personne n'a pas encore suggéré:

import unittest
# For python < 2.7, do import unittest2 as unittest

class Class(object):
    def should_raise(self):
        raise ValueError('expected arg')

class test_Class(unittest.TestCase):
    def test_something(self):
        DUT = Class()
        with self.assertRaises(ValueError) as exception_context_manager:
            DUT.should_raise()
        exception = exception_context_manager.exception

        self.assertEqual(exception.args, ('expected arg', ))


6 commentaires

Fonctionne bien pour moi. N'oubliez pas que vous devez le faire dans une méthode d'une instance unitest.descycase. Si vous utilisez une version plus ancienne de Python, vous devez également installer et utiliser Unitest2. Je vais développer ma réponse pour montrer l'exemple complet.


Vous m'avez sauvé des tonnes de fouilles. Merci.


C'est en fait une meilleure option que la réponse acceptée, IMHO. Au début, je pensais que cela ne fonctionnait pas sur mon Python 2.7 aussi, jusqu'à ce que je me rendais compte que vous ne pouvez pas accéder à context_manager.exception à partir de l'intérieur du quel bloc , comme j'étais en essayant. Le code dans cette réponse est correct, cependant, et fonctionne parfaitement. Merci pour cela.


@NeilenMarais - Pouvez-vous m'aider s'il vous plaît dans une question connexe? Stackoverflow.com/Questtions/39909935/...


@Boratsagdiyev On dirait que vous avez déjà une réponse acceptée, y a-t-il quelque chose que vous voudriez que je puisse ajouter?


@Neilenmarais - merci. Si vous souhaitez ajouter votre propre réponse, faites-le s'il vous plaît. Sinon, pouvez-vous s'il vous plaît vérifier si la réponse existante pourrait être améliorée de quelque manière que ce soit?



1
votes

Compte tenu de cela a été posé il y a six ans, j'imagine que c'est quelque chose qui fonctionne maintenant mais n'a pas fonctionné alors. Docs State Ceci est apparu en 2.7 mais pas lequel Micro version.

import unittest

class TestIntParser(unittest.TestCase):

    def test_failure(self):
        failure_message = 'invalid literal for int() with base 10'
        with self.assertRaises(ValueError) as cm:
            int('forty two')
        self.assertIn(failure_message, cm.exception.message)

if __name__ == '__main__':
    unittest.main()


1 commentaires

C'est presque exactement la même chose que Stackoverflow.com/a/13585289/1165509 répondit en 2012.