2010-03-28 11 views
7

Ho problemi nell'organizzazione del test di classe basato su unittest per la famiglia di test. Ad esempio, suppongo di implementare un'interfaccia "dizionario" e di avere 5 diverse implementazioni che desiderano testare.test di riutilizzo unittest per famiglie di classi

Scrivo una classe di test che verifica un'interfaccia del dizionario. Ma come posso riutilizzarlo per testare tutte le mie lezioni? Finora faccio brutta:

DictType = hashtable.HashDict 

In cima di file e quindi utilizzare DictType nella classe di test. Per testare un'altra classe, cambio manualmente il DictType in qualcos'altro.

Come si può fare diversamente? Non è possibile passare argomenti alle classi unittest quindi c'è un modo migliore?

risposta

5

Il modo in cui lo affronterò con lo standard unittest è la sottoclasse: la sovrascrittura dei dati è semplice come i metodi di sovrascrittura, dopo tutto.

così, ho una classe base per le prove:

class MappingTestBase(unittest.TestCase): 
    dictype = None 
    # write all the tests using self.dictype 

e sottoclassi:

class HashtableTest(MappingTestBase): 
    dictype = hashtable.HashDict 

class OtherMappingTest(MappingTestBase): 
    dictype = othermodule.mappingimpl 

Qui, le sottoclassi devono necessariamente la precedenza solo dictype. A volte è più facile esporre anche MappingTestBase utilizzando "metodi di aggancio". Quando i tipi testati non hanno interfacce esattamente identiche in tutti i casi, ciò può essere aggirato facendo in modo che le sottoclassi sostituiscano i metodi di aggancio secondo necessità - questo è il modello di progettazione "Metodo modello", vedi ad es. this page che ha una raccolta commentata e timelined di un paio di mie videoconferenze su modelli di progettazione - la parte II riguarda il metodo dei modelli e le relative varianti per circa i primi 30 minuti.

Non è necessario disporre di tutto questo in un singolo modulo, ovviamente (anche se spesso trovo più chiaro sistemare le cose in questo modo, potresti anche creare un modulo di test separato per tipo che stai testando, ogni import il modulo con la classe base astratta).

+0

oh, molto bello, 10x alex – zaharpopov

+0

Sto provando ad usare questo modello ma sto ricevendo errori (es. 'TypeError: 'NoneType' oggetto non è callable') perché il framework' unittest' esegue i test nel contesto di 'MappingTestBase' e ​​anche le classi derivate. C'è un modo per evitare che ciò accada ? – user200783

+0

@PaulBaker, certo, è possibile creare la suite di test che si desidera eseguire in modo esplicito, ad esempio utilizzando la classe 'TestLoader', vedere https://docs.python.org/2/library/unittest.html#unittest.TestLoader ad esempio, sottoclassi e sovrascrivendo 'getTestCaseNames' per restituire' [] 'per le classi i cui metodi di test non vuoi eseguire, oppure potresti decorare tutti i metodi di test per tornare solo se' self.dicttype è None'. gli approcci funzionano bene. –

0

Si potrebbe guardare testscenarios che consente di impostare un elenco chiamato scenari. Il codice genera quindi una versione della classe di test per ogni valore/scenario in lista

Vedi the example

Quindi nel tuo caso gli scenari sarebbero una lista come [{definire DictType: hashtable.HashDict}, {definire DictType : otherimpl.class},] e utilizzare self.dicttype nel codice di test.

+0

oh, quindi questo non è possibile con l'unittest standard? molto dissapointing :-( – zaharpopov

+0

Non ancora - vedi http://www.voidspace.org.uk/python/articles/unittest2.shtml per quello che viene fatto – Mark

Problemi correlati