68 votes

Obtenir les résultats les plus inégalés de Python dans une méthode tearDown ()

Est-il possible d'obtenir les résultats d'un test (c'est-à-dire si toutes les assertions ont réussi) dans une méthode tearDown ()? J'exécute des scripts Selenium, et j'aimerais faire quelques rapports à l'intérieur de tearDown (), mais je ne sais pas si c'est possible.

41voto

scoffey Points 2908

Si vous regardez l'implémentation de unittest.TestCase.run , vous pouvez voir que tous les résultats des tests sont collectés dans l'objet résultat (généralement une instance unittest.TestResult ) passé en argument. Aucun état de résultat n'est laissé dans l'objet unittest.TestCase .

Donc, vous ne pouvez pas faire grand-chose dans la méthode unittest.TestCase.tearDown moins que vous rompiez sans pitié l'élégant découplage des cas de test et des résultats de test avec quelque chose comme ceci:

 import unittest

class MyTest(unittest.TestCase):

    currentResult = None # holds last result object passed to run method

    def setUp(self):
        pass

    def tearDown(self):
        ok = self.currentResult.wasSuccessful()
        errors = self.currentResult.errors
        failures = self.currentResult.failures
        print ' All tests passed so far!' if ok else \
                ' %d errors and %d failures so far' % \
                (len(errors), len(failures))

    def run(self, result=None):
        self.currentResult = result # remember result for use in tearDown
        unittest.TestCase.run(self, result) # call superclass run method

    def test_onePlusOneEqualsTwo(self):
        self.assertTrue(1 + 1 == 2) # succeeds

    def test_onePlusOneEqualsThree(self):
        self.assertTrue(1 + 1 == 3) # fails

    def test_onePlusNoneIsNone(self):
        self.assertTrue(1 + None is None) # raises TypeError

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

13voto

Pavel Repin Points 13751

Mise en garde: je n'ai aucun moyen de vérifier la théorie qui suit à l'heure actuelle, d'être loin d'une boîte de dev. Donc cela peut être un coup de feu dans l'obscurité.

Vous pourriez peut-être vérifier la valeur de retour de l' sys.exc_info() à l'intérieur de votre tearDown() la méthode, si elle renvoie (None, None, None), vous savez que le cas de test a réussi. Sinon, vous pouvez utiliser retourné tuple à interroger l'objet de l'exception.

Voir sys.exc_info de la documentation.

Un autre plus explicite approche consiste à écrire une méthode décorateur que vous pourriez claque sur tous vos cas de test des méthodes qui nécessitent ce traitement spécial. Ce décorateur peut intercepter affirmation d'exceptions et de modifier certains de l'état en self permettant à vos démontage méthode pour apprendre ce qui est en place.

@assertion_tracker
def test_foo(self):
    # some test logic

10voto

amatellanes Points 1649

Si vous utilisez Python2, vous pouvez utiliser la méthode _resultForDoCleanups . Cette méthode renvoie un objet TextTestResult :

<unittest.runner.TextTestResult run=1 errors=0 failures=0>

Vous pouvez utiliser cet objet pour vérifier le résultat de vos tests:

 def tearDown(self):
    if self._resultForDoCleanups.failures:
        ...
    elif self._resultForDoCleanups.errors:
        ...
    else:
        #Success
 

Si vous utilisez Python3, vous pouvez utiliser _outcomeForDoCleanups :

 def tearDown(self):
    if not self._outcomeForDoCleanups.success:
        ...
 

9voto

hwjp Points 3041

Suite à la réponse d'Amatellanes, si vous êtes sur Python3.4, vous ne pouvez pas utiliser _outcomeForDoCleanups . Voici ce que j'ai réussi à pirater ensemble:

 def _test_has_failed(self):
    for method, error in self._outcome.errors:
        if error:
            return True
    return False
 

ouais, mais ça semble marcher.

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