Unittest setUp / tearDown für mehrere Tests

118

Gibt es eine Funktion, die zu Beginn / am Ende eines Testszenarios ausgelöst wird? Die Funktionen setUp und tearDown werden vor / nach jedem einzelnen Test ausgelöst.

Normalerweise möchte ich Folgendes haben:

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

Im Moment sind diese SetUp und TearDown Unit-Tests und verteilen sich auf alle meine Szenarien (die viele Tests enthalten). Einer ist der erste Test, der andere ist der letzte Test.

Schwan
quelle
6
Welche Version? Das unittest-Modul wurde um ein module_setup und ein module_teardown in Python 2.7 erweitert.
S.Lott
3
In 2.7 wurden auch die Klassenmethoden setUpClass () und tearDownClass () eingeführt, mit denen Sie mehrere Klassen in derselben Datei mit einem eigenen Setup und Teardown pro Suite haben können.
Per Fagrell

Antworten:

132

Ab 2.7 (gemäß Dokumentation ) erhalten Sie setUpClassund tearDownClasswelche vor und nach den Tests in einer bestimmten Klasse ausgeführt werden. Wenn Sie eine Gruppe von ihnen in einer Datei haben, können Sie alternativ setUpModuleund tearDownModule( Dokumentation ) verwenden.

Andernfalls besteht Ihre beste Wahl wahrscheinlich darin, Ihre eigene abgeleitete TestSuite zu erstellen und zu überschreiben run(). Alle anderen Aufrufe werden vom übergeordneten Element bearbeitet, und run führt Ihren Setup- und Teardown-Code für einen Aufruf bis zur runMethode des übergeordneten Elements auf .

David H. Clements
quelle
71

Ich habe das gleiche Szenario, für mich funktionieren die Methoden setUpClass und tearDownClass perfekt

import unittest

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

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()
V. Gupta
quelle
6
Dies sollte aktualisiert werden, um die akzeptierte Antwort zu sein, da es ein korrektes Beispiel zeigt und diese Funktionen Klassenmethoden sein MÜSSEN, um zu funktionieren, was in der akzeptierten Antwort nicht erwähnt wird.
NuclearPeon
1

Für Python 2.5 und bei der Arbeit mit Pydev ist es etwas schwierig. Es scheint, dass pydev die Testsuite nicht verwendet, sondern alle einzelnen Testfälle findet und alle separat ausführt.

Meine Lösung hierfür war die Verwendung einer Klassenvariablen wie folgt:

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

Wenn Sie mit diesem Trick von diesem TestCase(anstelle des Originals unittest.TestCase) erben, erben Sie auch den Wert runCount0. In der Ausführungsmethode wird dann der runCountuntergeordnete Testfall überprüft und inkrementiert. Dadurch bleibt die runCountVariable für diese Klasse bei 0.

Dies bedeutet, dass der setUpClassTest nur einmal pro Klasse und nicht einmal pro Instanz ausgeführt wird.

Ich habe noch keine tearDownClassMethode, aber ich denke, mit diesem Zähler könnte etwas erreicht werden.

sanderd17
quelle
0

Hier ein Beispiel: 3 Testmethoden greifen auf eine gemeinsam genutzte Ressource zu, die einmal und nicht pro Test erstellt wird.

import unittest
import random

class TestSimulateLogistics(unittest.TestCase):

    shared_resource = None

    @classmethod
    def setUpClass(cls):
        cls.shared_resource = random.randint(1, 100)

    @classmethod
    def tearDownClass(cls):
        cls.shared_resource = None

    def test_1(self):
        print('test 1:', self.shared_resource)

    def test_2(self):
        print('test 2:', self.shared_resource)

    def test_3(self):
        print('test 3:', self.shared_resource)
Kadir Malak
quelle