If a project has 30% coverage by unit tests, 40% due to integration tests, is it fair to say the total is 70% as so moderately well covered?
Solo se non vi è sovrapposizione tra il 40% coperto dai test di integrazione e il 30% coperto dai test unitari. Se c'è un codice coperto da entrambi i test, la copertura totale sarà inferiore al 70%.
Suggerimento: immagina che i numeri di copertura non siano il 30% e il 40% ma piuttosto il 60% e il 70%. Ora li aggiungi e hai una copertura del 130%, cioè stai testando un codice che non esiste nemmeno. Ti sembra sensato?
Or are unit tests only ever used as the standard test type for code coverage metrics?
No. Le metriche di copertura ti dicono semplicemente quale codice è stato eseguito. Periodo. Non è ciò che è stato eseguito per quel codice (test di integrazione, test unitari, test delle prestazioni, ecc.). Puoi anche utilizzare le metriche di copertura completamente al di fuori dei test, cioè raccogliere informazioni sulla copertura del codice dagli utenti per vedere quanto del tuo codice è effettivamente utilizzato e quanto è il peso morto. (Ad esempio, la consapevolezza che il 90% degli utenti di MS Office utilizza il 10% delle sue funzionalità e le modifiche nell'interfaccia utente che ha causato automaticamente nasconde le funzioni meno utilizzate per declinare i menu, ecc.)
Se si desidera misurare la copertura del test unitario, si eseguono i test unitari. Se si desidera misurare la copertura del test di integrazione, si eseguono i test di integrazione. Se vuoi misurare la copertura totale del test, esegui tutti i test e la copertura dei record in un colpo solo , ma non puoi semplicemente sommare i numeri.
Inoltre, non ha molto senso combinare i due: test unitari e test di integrazione hanno scopi molto diversi, danno garanzie molto diverse e hanno caratteristiche prestazionali molto diverse.
I test unitari testano un singolo comportamento in completo isolamento. Ciò li rende molto veloci (una suite di test di unità completa dovrebbe in genere funzionare in meno di 10 secondi, idealmente meno di 1). Ti consente di individuare con precisione qualsiasi problema su una singola unità di comportamento, in genere solo una singola riga di codice. Ti permette di eseguire costantemente i tuoi test unitari durante lo sviluppo in modo da cogliere eventuali potenziali bug introdotti in pochi secondi dall'introduzione, quando ancora conosci esattamente cosa hai cambiato, come e perché. Tuttavia, non garantiscono che il sistema funzioni: sono unità isolate minuscole, anche se tutte le unità funzionano al 100%, devono comunque essere cablate correttamente.
I test di integrazione testano l'interazione tra unità. In genere sono più lenti e un errore punta a un'area più ampia che devi cercare per il bug. A causa del loro tempo di esecuzione più lento, non è possibile eseguirli tutte le volte che si eseguono i test di unità, in genere si eseguono solo per un'interruzione, prima di un push, dopo un'unione, prima di un rilascio, ecc. Pertanto, il tempo di feedback sarà più lento . Nota: se hai test di integrazione molto rapidi e molto focalizzati, potresti essere in grado di eliminare (alcuni) i tuoi test unitari, poiché i test di integrazione possono servire il ruolo dei test unitari.
In aggiunta a ciò, hai ancora bisogno di test funzionali, test di accettazione, test delle prestazioni (sia micro che macro), test fuzz, test di usabilità, ...