Gli strumenti di copertura del codice funzionano in due versioni:
- il codice è instrumented per registrare le statistiche di copertura o
- il programma viene eseguito con un meccanismo debugger o profiler o tracing .
La misurazione della copertura è uno strumento di garanzia della qualità dinamico , poiché misura quale codice è eseguito . L'analisi statica non è sufficiente.
Se è disponibile un debugger, è facile interrompere l'esecuzione normale dopo ogni istruzione e registrare quella dichiarazione come coperta. Tuttavia, tutte queste interruzioni arrivano a un notevole runtime, il che rallenta i test. Gli strumenti di copertura basati su debugger sono spesso limitati dalle interfacce di debug in quali tipi di copertura possono essere raccolti. Per esempio. potresti non essere in grado di raccogliere la copertura delle filiali all'interno di espressioni come bar() && baz()
.
La strumentazione viene eseguita dal compilatore o da una fase di post-compilazione per iniettare il codice nell'eseguibile che registra la copertura. Il codice sorgente non è stato modificato. Questo ha un sovraccarico di runtime inferiore rispetto a una soluzione basata su debugger, ma richiede la compilazione del programma in una modalità di raccolta di copertura speciale.
Ad esempio, lo strumento python coverage.py
utilizza gli hook di traccia incorporati di Python. Al contrario, GCC e Clang supportano la raccolta di copertura basata sulla strumentazione durante la compilazione con i flag -fprofile-arcs -ftest-coverage
(è necessario disabilitare anche le ottimizzazioni e utilizzare un build di debugging: -g -O0
). Il vantaggio nella raccolta della copertura del ramo: il compilatore conosce tutti i rami presenti nel codice macchina, non solo i rami facilmente visibili nel codice sorgente. Quando il programma viene eseguito, registrerà la copertura in un file che può essere massaggiato in report con strumenti come gcov, lcov, gcovr e molti altri. (Divulgazione: mantengo gcovr.)
In generale, la misurazione della copertura richiede lo stesso tipo di dati di un profiler. Spesso, questi strumenti utilizzano esattamente la stessa infrastruttura. Tuttavia, un profiler può permettersi di essere meno preciso poiché i punti caldi verranno eseguiti spesso. A differenza degli strumenti di copertura, possono utilizzare campionamento per misurare la frequenza con cui viene eseguito il codice. Un profiler di campionamento interrompe regolarmente il processo e raccoglie una traccia di stack che punta alla posizione corrente. Questo accade meno spesso di ogni affermazione, spesso solo ogni pochi millisecondi. Quindi hanno un impatto minore sulle prestazioni, ma i loro dati sono meno precisi.