95 votes

Exécuter le setUp une seule fois pour un ensemble de tests automatisés

Ma version de Python est 2.6.

J'aimerais n'exécuter la méthode setUp du test qu'une seule fois, car j'y fais des choses qui sont nécessaires pour tous les tests.

Mon idée était de créer une variable booléenne qui serait mise à 'true' après la première exécution et ensuite de désactiver plus d'un appel à la méthode de configuration.

class mySelTest(unittest.TestCase):
    setup_done = False

    def setUp(self):
        print str(self.setup_done)
            
        if self.setup_done:
            return
        self.setup_done = True
        print str(self.setup_done)

Le résultat :

False

True

--- Test 1 ---

False

True

--- Test 2 ---

pourquoi cela ne fonctionne-t-il pas ? Ai-je manqué quelque chose ?

124voto

Daniel Roseman Points 199743

Vous pouvez utiliser setUpClass pour définir des méthodes qui ne s'exécutent qu'une fois par testuite.

74voto

Chemary Points 746

La réponse de Daniel est correcte, mais voici un exemple pour éviter certaines erreurs courantes que j'ai trouvées, comme le fait de ne pas appeler super() sur setUpClass() quand TestCase est une sous-classe de unittest.TestCase (comme dans django.test o falcon.testing ).

La documentation pour setUpClass() ne mentionne pas que vous devez appeler super() dans de tels cas. Si vous ne le faites pas, vous obtiendrez une erreur, comme dans l'exemple suivant cette question connexe .

class SomeTest(TestCase):
    def setUp(self):
        self.user1 = UserProfile.objects.create_user(resource=SomeTest.the_resource)

    @classmethod
    def setUpClass(cls):
        """ get_some_resource() is slow, to avoid calling it for each test use setUpClass()
            and store the result as class variable
        """
        super(SomeTest, cls).setUpClass()
        cls.the_resource = get_some_resource()

5voto

Greg Ross Points 3076

J'utilise Python 3 et j'ai constaté que la fonction cls est également disponible dans le setup et donc la méthode suivante fonctionne :

class TestThing(unittest.TestCase):

  @classmethod
  def setUpClass(cls):
    cls.thing = Thing() # the `thing` is only instantiated once

  def setup(self):
    self.thing = TestThing.thing # ...but set on each test case instance

  def test_the_thing(self):
    self.assertTrue(self.thing is not None)

3voto

jersey bean Points 506

Setup_done est une variable de classe, pas une variable d'instance.

Vous y faites référence en tant que variable d'instance :

self.setup_done

Mais vous devez la référencer comme une variable de classe :

mySelTest.setup_done

Voici le code corrigé :

class mySelTest(unittest.TestCase):
    setup_done = False

    def setUp(self):
        print str(mySelTest.setup_done)

        if mySelTest.setup_done:
            return
        mySelTest.setup_done = True
        print str(mySelTest.setup_done)

3voto

andi Points 1035

Si vous avez atterri ici parce que vous avez besoin de charger des données pour des tests... alors, si vous utilisez Django 1.9+, veuillez opter pour setUpTestData :

class MyTests(TestCase):

    @classmethod
    def setUpTestData(cls):
        # Set up data for the whole TestCase
        cls.foo = Foo.objects.create(bar="Test")

    def test1(self):
        self.assertEqual(self.foo.bar, 'Test')

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