web-dev-qa-db-fra.com

Unittest setUp / tearDown pour plusieurs tests

Existe-t-il une fonction qui est déclenchée au début/à la fin d'un scénario de test? Les fonctions setUp et tearDown sont activées avant/après chaque test.

Je voudrais typiquement avoir ceci:

class TestSequenceFunctions(unittest.TestCase):

    def setUpScenario(self):
        start() #launched at the beginning, once

    def test_choice(self):
        element = random.choice(self.seq)
        self.assertTrue(element in self.seq)

    def test_sample(self):
        with self.assertRaises(ValueError):
            random.sample(self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assertTrue(element in self.seq)

    def tearDownScenario(self):
        end() #launched at the end, once

Pour l'instant, ces instructions setUp et tearDown sont des tests unitaires et sont répandues dans tous mes scénarios (contenant de nombreux tests), l'un étant le premier test, l'autre le dernier.

105
swan

À partir de 2.7 (par la documentation ), vous obtenez setUpClass et tearDownClass qui s'exécutent avant et après les tests d'une classe donnée, respectivement. Sinon, si vous en avez un groupe dans un fichier, vous pouvez utiliser setUpModule et tearDownModule ( documentation ).

Sinon, votre meilleur choix sera probablement de créer votre propre dérivé TestSuite et de remplacer run(). Tous les autres appels seraient gérés par le parent, et run appellerait votre code d'installation et de démontage autour d'un appel de la méthode run du parent.

124
David H. Clements

J'ai le même scénario, pour moi les méthodes setUpClass et tearDownClass fonctionnent parfaitement

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()
47
V.Gupta

Pour python 2.5, et lorsque vous travaillez avec pydev, c'est un peu difficile. Il semble que pydev n'utilise pas la suite de tests, mais recherche tous les scénarios de test individuels et les exécute tous séparément.

Ma solution pour cela utilisait une variable de classe comme celle-ci:

class TestCase(unittest.TestCase):
    runCount = 0

    def setUpClass(self):
        pass # overridden in actual testcases

    def run(self, result=None):
        if type(self).runCount == 0:
            self.setUpClass()

        super(TestCase, self).run(result)
        type(self).runCount += 1

Avec cette astuce, lorsque vous héritez de cette TestCase (au lieu de l'original unittest.TestCase), vous héritez également du runCount de 0. Ensuite, dans la méthode d'exécution, le runCount du testcase enfant est vérifié et incrémenté. Cela laisse la variable runCount pour cette classe à 0.

Cela signifie que setUpClass ne sera exécuté qu'une fois par classe et non par instance.

Je n'ai pas encore de méthode tearDownClass, mais je suppose que quelque chose pourrait être fait avec l'utilisation de ce compteur.

1
sanderd17