2013-02-18 14 views
6

Sto convertendo la suite di test di un progetto Python da unittest a nose. Il framework esistente del progetto (basato su unittest) è piuttosto goffo, contenente un sacco di codice fortemente personalizzato per il rilevamento dei test e l'esecuzione, quindi sto cercando di migrare verso il naso per rendere tutto più snello.Ereditarietà test del naso di pitone: unità di prova dell'unità di carico da sottoclassi

Ho riscontrato problemi con il codice che sta generando le suite di test, tuttavia.

Il framework del progetto ha due modalità di esecuzione dei test. Uno è

class TestSomething(unittest.TestCase): 

    def setUp(self): 
     ... 

    def test_x(self): 
     ... 

    def test_y(self): 
     ... 

suite = unittest.TestSuite() 
suite.addTest(unittest.makeSuite(TestSomething)) 

che è il modo "semplice", è quello che tutti gli esempi naso e tutorial mostrano, e funziona. Tuttavia, il secondo modo è quello di definire una classe di test che contiene tutta la logica di test, quindi creando casi di test in varie sottoclassi che contengono configurazioni di installazione diverse e ereditano le prove dalla superclasse:

class TestSomething(unittest.TestCase): 

    def test_x(self): 
     ... 

    def test_y(self): 
     ... 

class TestCase1(TestSomething): 

    def setUp(self): 
     ... 

class TestCase2(TestSomething): 

    def setUp(self): 
     ... 

suite = unittest.TestSuite() 

cases = [TestCase1,TestCase2] 
suite.addTests([unittest.makeSuite(case) for case in cases]) 

Questo è quello Nose fallisce con. Cerca di eseguire prima i metodi di test, che ovviamente non funzionano perché non c'è setUp() nella superclasse e molte delle variabili utilizzate in test_x() e test_y() non sono ancora state definite.

Non ho trovato alcun esempio di questo fatto da nessuna parte, e la documentazione di Nose (piuttosto scarsa e difficile da navigare) non sembra menzionarla neanche. Come può essere fatto per lavorare con il naso? Qualsiasi aiuto sarà molto apprezzato.

risposta

13

Prima di tutto, come unutbu notato, non si deve dare per TestSomething un nome che inizia con Test, perché nose trattamento automatico di tali classi come test-casi. Inoltre, nose gestisce tutte le sottoclassi TestCase che trova, facendo in tal modo:

class Something(unittest.TestCase): 
    ... 

dà esattamente gli stessi risultati che si stanno avendo. Penso che non si dovrebbe ereditare da TestCase e utilizzare questa classe come un mix-in:

class Something(object): 
    def test_x(self): 
     # here the various assertEqual etc. do not resolve, but you can use them 
     # as if they were present, since in real test-cases they will be inherited 
     # from unittest.TestCase. 
     ... 
    ... 

class TestCase1(unittest.TestCase, Something): 
    def setUp(self): 
     ... 

Un altro modo per farlo è quello di impostare la classe __test__ attributo per False:

class TestSomething(unittest.TestCase): 
    __test__ = False 
    def test_x(self): 
     ... 


class TestCase1(TestSomething): 
    __test__ = True #must put this 
    def setUp(self): 
     ... 

In alternativa si può usare nose.istest e nose.nottest per contrassegnare quale classe è un TestCase e quale non lo è:

@tools.nottest 
class TestSomething(unittest.TestCase): 
    def test_x(self): 
     ... 

@tools.istest 
class TestCase1(TestSomething): 
    sef setUp(self): 
     ... 
+0

Utilizzando il decoratore naso s ha fatto il trucco; guardando indietro, sembra molto ovvio ora ma a volte le soluzioni più ovvie sono le più elusive ... molte grazie per i suggerimenti! – Boris

Problemi correlati