2012-02-08 12 views
17

devo una classe base astratta lungo le linee di:Esclusione abstractproperties da copertura riporta

class MyAbstractClass(object): 
    __metaclass__ = ABCMeta 

    @abstractproperty 
    def myproperty(self): pass 

Ma quando corro nosetests (che la copertura) sul mio progetto, si lamenta che la linea di proprietà def è testato. Non può realtà da testare (per quanto ne so) come istanza della classe astratta si tradurrà in un'eccezione di essere sollevato ..

ci sono delle soluzioni a questo, o devo semplicemente accettare la copertura dei test < 100% ?

Ovviamente, è possibile rimuovere l'utilizzo di ABCMeta e semplicemente aumentare la classe di base NotImpementedError, ma preferisco il metodo precedente.

risposta

21

Non esiste alcun modo per escludere le proprietà astratte esattamente come si dispone, ma se si effettua un leggero cambiamento, è possibile. Avere la proprietà astratta generare un errore:

@abstractproperty 
def myproperty(self): 
    raise NotImplementedError 

Quindi è possibile istruire coverage.py di ignorare le linee che sollevano NotImplementedError. Creare un file .coveragerc, e in essa mettere:

[report] 
exclude_lines = 
    # Have to re-enable the standard pragma 
    pragma: no cover 

    # Don't complain if tests don't hit defensive assertion code: 
    raise NotImplementedError 

Per ulteriori idee sulle tipologie di linee che si potrebbe desiderare di ignorare sempre, vedi: http://nedbatchelder.com/code/coverage/config.html

+0

Alla fine ho scoperto "#pragma: no cover" su IRC e sono andato con quello in linea. Non sono un fan di avere un'implementazione in una proprietà astratta (anche se è solo "sollevare NotImplementedError" in quanto sembra sconfiggere lo scopo). –

+3

wait: stai bene inserendo un commento "#pragma: no cover" su ogni proprietà astratta, ma non sei d'accordo nel cambiare il corpo da pass a "raise NotImplementedError"? A ciascuno il suo, immagino ... Felice che tu abbia trovato una soluzione che ti piace. –

+0

Sono assolutamente d'accordo che non è una soluzione ottimale, ma preferisco usare le direttive inline come quella di alterare l'uso e il beneficio del modulo di classe base astratto. –

22

Per me la soluzione migliore è stato quello @Wesley menzionato nel suo commento alla risposta accettata, in particolare sostituendo 'pass' con un docstring per la proprietà astratta, ad esempio:

class MyAbstractClass(object): 
    __metaclass__ = ABCMeta 

    @abstractproperty 
    def myproperty(self): 
     """ this property is too abstract to understand. """ 
1

ho personalizzato saltare la logica nel mio .coveragerc:

[report] 
exclude_lines = 
    pragma: no cover 
    @abstract 

In questo modo tutti i metodi abstractmethods e abstractproperties sono contrassegnati come saltati.