2014-07-10 8 views
12

attualmente hanno un progetto configurato per eseguire la copertura tramite il comando gestore di Django in questo modo:Come testare una copertura correttamente con Django + Nose

Questo si traduce in un rapporto come il seguente:

Name      Stmts Miss Branch BrMiss Cover Missing 
-------------------------------------------------------------------------- 
notify.decorators    4  1  0  0 75% 4 
notify.handlers     6  1  2  0 88% 11 
notify.notification_types  46  39  2  0 19% 8-55, 59, 62, 66 
notify.notifications   51  51  0  0  0% 11-141 
-------------------------------------------------------------------------- 
TOTAL       107  92  4  0 17% 

Tuttavia, c'è un problema con questo rapporto. È sbagliato. La copertura segna le linee mancanti, nonostante siano effettivamente coperte da test.

Name      Stmts Miss Branch BrMiss Cover Missing 
----------------------------------------------------------------------------- 
notify.decorators    4  0  0  0 100% 
notify.handlers     6  0  2  0 100% 
notify.notification_types  46  0  2  0 100% 
notify.notifications   51  25  0  0 51% 13, 18, 23, 28, 33, 38, 43, 48, 53, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 116, 121, 126, 131, 136, 141 
----------------------------------------------------------------------------- 
TOTAL       107  25  4  0 77% 

Google mi ha portato a FAQ del sito web di copertura, http://nedbatchelder.com/code/coverage/faq.html

D:: Per esempio, se si esegue il test tramite nosetests invece di Django del comando ottengo il seguente corretto rapporto gestire Perché la corpi di funzioni (o classi) mostrano come eseguiti, ma le linee di def non lo fanno?

Ciò accade perché la copertura viene avviata dopo la definizione delle funzioni. Le linee di definizione vengono eseguite senza misurazione della copertura, quindi viene avviata la copertura, quindi viene richiamata la funzione. Ciò significa che il corpo è misurato, ma la definizione della funzione stessa non lo è.

Per risolvere questo problema, avviare la copertura in precedenza. Se si utilizza la riga di comando per eseguire il programma con copertura, verrà monitorato l'intero programma. Se si utilizza l'API, è necessario chiamare coverage.start() prima di importare i moduli che definiscono le proprie funzioni.

La domanda è: posso eseguire correttamente i rapporti di copertura tramite il comando di gestione di Django? O devo bypassare gestire per evitare la situazione in cui viene avviata la copertura dopo l'esecuzione delle linee "mancanti"?

risposta

12

Al momento non è possibile eseguire con precisione la copertura insieme a django-nose (a causa del modo in cui Django 1.7 carica i modelli). Quindi, per ottenere le statistiche di copertura, è necessario utilizzare coverage.py direttamente dalla linea di comando, ad esempio:

$ coverage run --branch --source=app1,app2 ./manage.py test 
$ coverage report 
$ coverage html -d coverage-report 

È possibile inserire le impostazioni in un file coverage.py .coveragerc nella root del progetto (la stessa dir di gestire. py).

Questo problema è riportato nella pagina GitHub di django-nose: https://github.com/django-nose/django-nose/issues/180 in modo che i manutentori siano a conoscenza del problema, puoi far loro sapere che stai riscontrando questo problema.

UPDATE

eliangcs sottolineato (problemi django-naso su GiHub), che woraround è quello di modificare il vostro manage.py:

import os 
import sys 

if __name__ == "__main__": 
    # ... 
    from django.core.management import execute_from_command_line 

    is_testing = 'test' in sys.argv 

    if is_testing: 
     import coverage 
     cov = coverage.coverage(source=['package1', 'package2'], omit=['*/tests/*']) 
     cov.erase() 
     cov.start() 

    execute_from_command_line(sys.argv) 

    if is_testing: 
     cov.stop() 
     cov.save() 
     cov.report() 

Funziona, ma è piuttosto "hacky" approccio.

UPDATE 2

consiglio per tutti coloro che utilizza il naso di avere uno sguardo a py.test (http://pytest.org/), che è veramente buono strumento di test Python, si integra bene con Django, ha un sacco di plugin e molti altri. Stavo usando il django-nose, ma ho provato py.test e non ho mai guardato indietro.

+1

Questa è la soluzione più comoda (anche se hacky) e funziona perfettamente e in modo trasparente con il naso django – danigosa

5

Come i documenti dicono, "utilizzare la riga di comando per eseguire il programma con una copertura":

coverage run --branch --source=notify ./manage.py test 
+0

Grazie Ned. La mia domanda riguardava specificamente se è possibile o meno eseguire la gestione e ottenere i risultati corretti. Avrei ragione nel presumere che no, non c'è modo? – kaptainlange

+0

Non so perché --with-coverage funziona per alcune persone e non per altre. –

0

sono riuscito a ottenere questo lavoro tra cui un

import coverage 

in cima alla mia manage.py file (sto usando Flask, ma ho lo stesso problema)

Il mio problema è che funziona da console ma Jenkins non ne è a conoscenza e continua a dire che quelle importazioni sono fuori dalla te sts ...

Qualche idea?

0

Ho avuto lo stesso problema utilizzando un interprete remoto in una macchina virtuale tramite la configurazione ssh. La soluzione era quella di impostare la directory dei miei test e ALL le sue directory madri nelle "Mappature dei percorsi" della sezione "Ambiente" di "Esegui"> "Modifica configurazioni ...".