Quelle est la différence entre setUp () et setUpClass () dans Python unittest?

99

Quelle est la différence entre setUp()et setUpClass()dans le unittestframework Python ? Pourquoi la configuration serait-elle gérée d'une manière plutôt que d'une autre?

Je veux comprendre quelle partie de la configuration est effectuée dans les fonctions setUp()et setUpClass(), ainsi qu'avec tearDown()et tearDownClass().

etja
la source

Réponses:

147

La différence se manifeste lorsque vous avez plus d'une méthode de test dans votre classe. setUpClasset tearDownClasssont exécutés une fois pour toute la classe; setUpet tearDownsont exécutés avant et après chaque méthode de test.

Par exemple:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    def setUp(self):
        print("setUp")

    def test1(self):
        print("test1")

    def test2(self):
        print("test2")

    def tearDown(self):
        print("tearDown")

    @classmethod
    def tearDownClass(cls):
        print("tearDownClass")

Lorsque vous exécutez ce test, il imprime:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(Les points ( .) sont unittestla sortie par défaut de quand un test réussit.) Observez cela setUpet tearDownapparaissent avant et après test1 et test2 , tandis que setUpClasset tearDownClassn'apparaissent qu'une seule fois, au début et à la fin de l'ensemble du scénario de test.

Benjamin Hodgson
la source
L'ordre ne devrait-il pas être celui-ci? : setUpClass setUp test1 tearDown .setUp test2 .tearDown tearDownClass
Jai Sharma
Remarquez le "." devant tearDown et l'absence de "." in front of tearDownClass
Jai Sharma
Ah, désolé, je n'ai pas remarqué ça. Non, unittestne considère pas qu'un test a réussi tant qu'il ne tearDowns'est pas terminé sans incident.
Benjamin Hodgson
Donc, chacune des méthodes test1 et test2 devrait avoir son propre ensemble de setUp & tearDown, non? Dans votre réponse, test1 n'a pas de méthode tearDown et devrait donc avoir imprimé la sortie par défaut (avec le.). Corrige moi si je me trompe.
Jai Sharma
1
Le résultat de la réponse est correct. Je l'ai collé directement à partir de la sortie d'unittest. setUpet tearDownsont chacun exécutés une fois pour chaque testméthode (donc deux fois au total dans cet exemple) mais setUpClasset tearDownClasssont exécutés une seule fois chacun.
Benjamin Hodgson
15

Quelle est la différence entre setUp()et setUpClass()dans le unittestframework Python ?

La principale différence (comme indiqué dans la réponse de Benjamin Hodgson) est qu'elle setUpClassn'est appelée qu'une seule fois et c'est avant tous les tests, alors qu'elle setUpest appelée immédiatement avant chaque test. (NB: la même chose s'applique aux méthodes équivalentes dans d'autres frameworks de test xUnit, pas seulement à Python unittest.)

De la unittest documentation :

setUpClass()

Une méthode de classe appelée avant l'exécution des tests dans une classe individuelle. setUpClass est appelé avec la classe comme seul argument et doit être décoré comme une méthode de classe ():

@classmethod
def setUpClass(cls):
    ...

et:

setUp()

Méthode appelée pour préparer le montage d'essai. Ceci est appelé immédiatement avant d'appeler la méthode de test; autre que AssertionError ou SkipTest, toute exception déclenchée par cette méthode sera considérée comme une erreur plutôt que comme un échec de test. L'implémentation par défaut ne fait rien.

Pourquoi la configuration serait-elle gérée d'une manière plutôt que d'une autre?

Cette partie de la question n'a pas encore reçu de réponse. Selon mon commentaire en réponse à la réponse de Gearon, la setUpméthode est destinée aux éléments du montage qui sont communs à tous les tests (pour éviter de dupliquer ce code dans chaque test). Je trouve que cela est souvent utile car la suppression de la duplication (généralement) améliore la lisibilité et réduit la charge de maintenance.

La setUpClassméthode est pour les éléments coûteux que vous préférez ne faire qu'une seule fois, comme l'ouverture d'une connexion à une base de données, l'ouverture d'un fichier temporaire sur le système de fichiers, le chargement d'une bibliothèque partagée pour les tests, etc. Faire de telles choses avant chaque test ralentirait le suite de tests trop, donc nous le faisons juste une fois avant tous les tests. Il s'agit d'une légère dégradation de l'indépendance des tests mais d'une optimisation nécessaire dans certaines situations. On ne devrait sans doute pas faire de telles choses dans les tests unitaires car il est généralement possible de se moquer de la base de données / système de fichiers / bibliothèque / quoi que ce soit sans utiliser la chose réelle. En tant que tel, je trouve que setUpClassc'est rarement nécessaire. Cependant, il est utile lorsque le test des exemples ci-dessus (ou similaire) devient nécessaire.

Biggsy
la source