2013-01-13 33 views
37

La mia versione di Python è 2.6.Esegui setUp solo una volta

Vorrei eseguire il metodo setUp solo una volta poiché sto facendo le cose che sono necessarie per ogni test.

La mia idea era di creare una variabile booleana che sarà impostata su "true" dopo la prima esecuzione.

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) 

L'output:

False 

True 

--- Test 1 --- 

False 

True 

--- Test 2 --- 

perché questo non funziona? Mi sono perso qualcosa?

+4

Unittest crea istanze separate per ciascuna prova –

+2

Non eseguire questa operazione. Implementare qualche altro meccanismo. Ma non provare a cambiare il significato di 'setUp'. –

+0

Possibile duplicato di [Unittest setUp/tearDown per diversi test] (https://stackoverflow.com/questions/8389639/unittest-setup-teardown-for-several-tests) –

risposta

62

È possibile utilizzare setUpClass per definire i metodi eseguiti una sola volta per testuite.

+0

Grazie per la risposta. Dato che sto usando Python 2.6.6 setUpClass non è disponibile. – Kesandal

+2

@JohnM .: Puoi scaricare il pacchetto di backport unittest2 e ottenere tutte le novità sul tuo python-dist precedente. – Macke

2

Non tentare di deduplicare le chiamate a setUp, basta chiamarlo una volta.

Ad esempio:

class MyClass(object): 
    ... 

def _set_up(): 
    code to do one-time setup 

_set_up() 

Ciò richiederà _set_up() quando il modulo è caricato prima. L'ho definito come una funzione a livello di modulo, ma potresti ugualmente renderlo un metodo di classe di MyClass.

0

Inserire tutto il codice che si desidera impostare una volta all'esterno di mySelTest.

setup_done = False 

class mySelTest(unittest.TestCase): 

    def setUp(self): 
     print str(setup_done) 

     if setup_done: 
      return 

     setup_done = True 
     print str(setup_done) 

Un'altra possibilità è avere una classe Singleton che si crea un'istanza in setUp(), che si svolgerà solo il codice __new__ una volta e restituire l'istanza dell'oggetto per il resto delle chiamate. Vedere: Is there a simple, elegant way to define singletons?

class Singleton(object): 
    _instance = None 
    def __new__(cls, *args, **kwargs): 
     if not cls._instance: 
      cls._instance = super(Singleton, cls).__new__(
          cls, *args, **kwargs) 
      # PUT YOUR SETUP ONCE CODE HERE! 
      cls.setUpBool = True 

     return cls._instance 

class mySelTest(unittest.TestCase): 

    def setUp(self): 
     # The first call initializes singleton, ever additional call returns the instantiated reference. 
     print(Singleton().setUpBool) 

Il tuo modo di lavorare troppo però.

+0

Cura di spiegare il downvote? – NuclearPeon

29

Daniel's answer è corretto, ma qui è un esempio per evitare alcuni errori comuni che ho trovato, come ad esempio non chiamare super() in setUpClass().

La documentazione per setUpClass() non indica che è necessario chiamare super(). Se non lo fai, visualizzerai un errore, come mostrato in this related question.

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()