web-dev-qa-db-fra.com

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

Quelle est la différence entre setUp() et setUpClass() dans le framework Python unittest? Pourquoi la configuration serait-elle gérée d'une méthode à l'autre?

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

57
etja

La différence se manifeste lorsque vous avez plus d'une méthode de test dans votre classe. setUpClass et tearDownClass sont exécutés une fois pour toute la classe; setUp et tearDown sont 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 affiche:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(Les points (.) sont la sortie par défaut de unittest quand un test réussit.) Notez que setUp et tearDown apparaissent avant et après test1 et test2, alors que setUpClass et tearDownClass apparaissent une seule fois, au début et à la fin du test. Cas.

101
Benjamin Hodgson

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

La principale différence (comme l'indiquait Benjamin Hodgson dans sa réponse) est que setUpClass n'est appelée qu'une seule fois, c'est-à-dire avant tous les tests, tandis que setUp est appelée immédiatement avant chaque test. (NB: il en va de même pour les méthodes équivalentes dans d'autres frameworks de test xUnit, pas seulement dans unittest de Python.)

De la unittestdocumentation :

setUpClass()

Une méthode de classe appelée avant les tests d'une classe individuelle est exécutée. setUpClass est appelé avec la classe comme seul argument et doit être décoré comme un classmethod ():

@classmethod
def setUpClass(cls):
    ...

et:

setUp()

Méthode appelée pour préparer le montage de test. Ceci est appelé immédiatement avant d'appeler la méthode de test; À l'exception de 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 méthode à l'autre?

Cette partie de la question n'a pas encore reçu de réponse. Conformément à mon commentaire en réponse à la réponse de Gearon, la méthode setUp est destinée aux éléments de la fixture 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 méthode setUpClass concerne les éléments coûteux que vous n’auriez à faire qu’une fois, comme ouvrir une connexion à une base de données, ouvrir un fichier temporaire sur le système de fichiers, charger une bibliothèque partagée à des fins de test, etc. test ralentirait trop la suite de tests, nous le faisons donc 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 peut soutenir que les tests unitaires ne doivent pas être réalisés de la sorte, car il est généralement possible de se moquer de la base de données/du système de fichiers/de la bibliothèque/de tout ce que vous voulez sans utiliser de choses réelles. En tant que tel, je trouve que setUpClass est rarement nécessaire. Cependant, il est utile de tester les exemples ci-dessus (ou similaires).

2
Biggsy

Après avoir lu la question et la réponse acceptée, je pense qu’un supplément peut être ajouté. 

Q: Pourquoi la configuration serait-elle gérée de l'une à l'autre?
A: C’est parce que la méthode d’essai peut avoir besoin d’être préliminaire et que celle-ci varie d’une méthode d’essai à l’autre. 

Par exemple, prenez le code ci-dessous de https://www.tutorialspoint.com/unittest_framework/unittest_framework_api.htm en exemple:

import unittest

class simpleTest2(unittest.TestCase):
   def setUp(self):
      self.a = 10
      self.b = 20
      name = self.shortDescription()
      if name == "add":
         self.a = 10
         self.b = 20
         print name, self.a, self.b
      if name == "sub":
         self.a = 50
         self.b = 60
         print name, self.a, self.b
   def tearDown(self):
      print '\nend of test',self.shortDescription()

   def testadd(self):
      """add"""
      result = self.a+self.b
      self.assertTrue(result == 30)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)

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

La méthode testadd et testsub nécessite une entrée différente et nous pouvons définir la valeur de l'entrée respectivement dans la méthode setUp

0
Gearon