Le Code Coverage (couverture de code) est une métrique qui montre quel pourcentage du code source d’une application est exécuté pendant les tests. Elle aide à déterminer la qualité des tests, identifier les zones non vérifiées et prioriser l’écriture de nouveaux tests. Selon Atlassian, 2025, le niveau optimal de couverture est de 70–80 % — au-delà de ce seuil, les coûts des tests commencent à dépasser les bénéfices.
Points clés
Code Coverage (couverture de code) est une métrique quantitative qui détermine quelle partie du code source de l’application a été exécutée pendant les tests. Elle est exprimée en pourcentage et calculée comme le rapport des lignes/branches exécutées au total. Une couverture élevée ne garantit pas l’absence de bugs, mais réduit le risque d’erreurs non détectées.
La couverture de code aide l’équipe à : trouver les zones non testées du code, prendre des décisions sur les priorités d’écriture de tests et suivre la dynamique de qualité des tests dans le CI/CD. Dans le développement mobile, la couverture est particulièrement importante pour la logique métier, les modèles de données et les repositories — les couches où la probabilité d’erreurs est la plus élevée.
Un mythe courant : « 100 % de couverture = qualité parfaite ». En pratique, une couverture de 100 % est extrêmement rare et souvent obtenue au prix de tests superficiels. La couverture efficace n’est pas une course au pourcentage, mais une couverture stratégique des chemins critiques et des cas limites. La couverture ne dit rien sur la qualité des tests eux-mêmes : un test peut réussir sans vérifier la correction du résultat.
Il existe plusieurs métriques de Code Coverage, chacune mesurant différents aspects des tests. Line coverage (couverture de ligne) est la métrique la plus simple, montrant le pourcentage de lignes de code exécutées. Branch coverage (couverture de branche) mesure quelles ramifications if-else et switch ont été testées.
Line coverage compte chaque ligne de code source comme exécutée ou non. Si une ligne contient un opérateur conditionnel ou une boucle, la ligne est considérée exécutée si le contrôle l’a atteinte, même si toutes les branches n’ont pas été traitées. C’est la métrique la moins stricte, mais la plus compréhensible pour une évaluation visuelle.
Branch coverage évalue si toutes les branches possibles dans le code ont été testées. Pour chaque if-else, les deux branches sont considérées : true et false. Pour switch, chaque case est considéré. Branch coverage est considérée comme une métrique plus stricte que line coverage et révèle plus souvent des scénarios non testés.
| Métrique | Ce qu’elle mesure | Difficulté d’atteinte |
|---|---|---|
| Line | Pourcentage de lignes de code exécutées | Faible |
| Branch | Pourcentage de branches exécutées (if/else, switch) | Moyenne |
| Function | Pourcentage de fonctions et méthodes appelées | Faible |
| Condition | Pourcentage de sous-expressions logiques (&&, ||) | Élevée |
Path coverage est la métrique la plus stricte, nécessitant la vérification de toutes les combinaisons possibles de branches dans une fonction. En pratique, path coverage est rarement utilisé en raison de la croissance exponentielle du nombre de combinaisons : une fonction avec 10 branches a 1024 chemins possibles.
Dans le développement mobile, divers outils sont utilisés pour mesurer le Code Coverage selon la plateforme. Pour Android, la norme est JaCoCo (Java Code Coverage), qui s’intègre avec Gradle et prend en charge à la fois les tests unitaires et les tests d’instrumentation. Pour iOS, XCCov est utilisé, intégré à Xcode.
JaCoCo génère des rapports aux formats HTML, XML et CSV. Le rapport HTML met visuellement en évidence les lignes : vert — exécutées, rouge — omises, jaune — partiellement exécutées. Le rapport XML est compatible avec SonarQube et d’autres systèmes d’analyse de code. JaCoCo prend en charge le filtrage des classes : le code généré, le databinding et BuildConfig peuvent être exclus.
// build.gradle — configuration JaCoCo
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
// Génération du rapport JaCoCo
task jacocoTestReport(type: JacocoReport) {
dependsOn 'testDebugUnitTest'
reports {
xml.enabled = true
html.enabled = true
}
}
XCCov est un outil intégré à Xcode pour mesurer la couverture de code. Il s’active via Gather coverage data dans le schéma de test. XCCov prend en charge la couverture pour Swift et Objective-C, génère des rapports au format .xccovreport et s’intègre avec CI via xcodebuild -enableCodeCoverage YES. Les données sont affichées dans la console et peuvent être exportées en JSON.
Pour la surveillance centralisée de la couverture, des plateformes comme SonarQube (analyse de qualité de code + couverture), Codecov et Coveralls sont utilisées. Ces services agrègent les données de JaCoCo et XCCov, montrent les tendances, les Quality Gates et l’intégration avec GitHub/GitLab via des commentaires de PR.
L’amélioration du Code Coverage nécessite une approche systématique : non pas « augmenter les pourcentages », mais couvrir les risques. La première étape consiste à analyser le rapport JaCoCo ou XCCov — identifier les classes rouges (non couvertes). Priorité : logique métier → repositories → ViewModel → composants d’interface.
Le Test-Driven Development (TDD) assure automatiquement une couverture élevée, car les tests sont écrits avant l’implémentation. Le processus : rouge (écrire un test qui échoue) → vert (écrire le code minimal) → refactorisation. TDD discipline le développeur, le forçant à couvrir les cas limites et les situations exceptionnelles qui restent souvent sans test.
Un test paramétré remplace des dizaines de tests ordinaires. JUnit et XCTest prennent en charge la paramétrisation : @ParameterizedTest dans JUnit 5, XCTestCase avec testPerformanceExample dans XCTest. La paramétrisation permet de vérifier de multiples données d’entrée sans duplication de code, ce qui étend considérablement la couverture des branches et des conditions.
// Test paramétré en Kotlin avec JUnit 5
@ParameterizedTest
@ValueSource(strings = ["user@test.com", "admin@test.com", "test@example.com"])
fun `validate email returns true for valid addresses`(email: String) {
val result = EmailValidator.isValid(email)
Assertions.assertTrue(result)
}
L’erreur la plus fréquente est la poursuite du pourcentage sans analyser la qualité des tests. L’équipe commence à écrire des tests pour les tests : vérifier les getters et setters, dupliquer la couverture à différents niveaux, tester des méthodes triviales. Cela donne un pourcentage élevé mais n’améliore pas la qualité réelle.
Un Code Coverage élevé peut créer un faux sentiment que l’application est bien testée. Un test peut exécuter une ligne de code mais ne pas vérifier la correction du résultat. Par exemple : un test appelle une méthode de calcul de remise mais ne vérifie pas le montant — la ligne est exécutée, la couverture augmente, mais le bug n’est pas trouvé.
Une erreur typique consiste à tester uniquement le « chemin heureux » (happy path) et ignorer les cas limites : listes vides, valeurs nulles, nombres maximaux, formats incorrects. C’est précisément aux limites et aux exceptions que surviennent la plupart des bugs. Branch coverage aide à identifier les branches manquées, mais ne garantit pas la vérification des valeurs limites.
Le Mutation Testing est une méthode d’évaluation de la qualité des tests où des mutations (erreurs artificielles) sont introduites dans le code source et on vérifie si les tests échouent. Pitest est un outil populaire de mutation testing pour Java et Kotlin. Si les tests n’échouent pas sur une mutation, cela signifie qu’ils ne vérifient pas cette condition.
Pitest crée des mutants — des copies modifiées du code source où, par exemple, > est remplacé par >=, true par false, ou un appel de méthode est supprimé. Ensuite, pour chaque mutant, les tests sont exécutés. Si les tests réussissent — le mutant a survécu, ce qui signifie que les tests ne couvrent pas ce scénario. Si les tests échouent — le mutant est tué, le test est valide.
// build.gradle — configuration Pitest
plugins {
id 'info.solidsoft.pitest' version '1.15.0'
}
pitest {
targetClasses = ['com.example.app.*']
targetTests = ['com.example.app.*Test']
threads = 4
outputFormats = ['HTML', 'XML']
mutationThreshold = 80
coverageThreshold = 85
}
Pitest prend en charge de nombreux types de mutations : modification des opérateurs conditionnels (== → !=, < → <=), suppression d’appels de méthode, remplacement des valeurs de retour (true → false), modification des opérations arithmétiques (+ → -), mutation des incréments (i++ → i--). Plus les types de mutations sont tués par les tests, plus la suite de tests est fiable.
Le mutation score cible est de 80 % ou plus. Cela signifie que 80 % des erreurs artificielles sont détectées par les tests. Une couverture de code (Code Coverage) de 90 % ne garantit pas que les tests trouvent des bugs — le mutation testing fournit une évaluation plus objective. Pitest peut être intégré dans le CI en tant que Quality Gate, bloquant le build si le mutation score tombe sous le seuil.
Pour le contrôle automatique du Code Coverage dans le CI/CD, des Quality Gates sont utilisés — des valeurs seuils qui, lorsqu’elles sont violées, marquent le build comme instable ou le rejettent. SonarQube permet de configurer un Quality Gate basé sur une combinaison de métriques : couverture (≥80 %), nombre de bugs, vulnérabilités et code dupliqué.
Dans GitHub Actions, le Code Coverage est intégré via des étapes d’action : exécuter les tests avec couverture → télécharger le rapport vers Codecov → vérifier le seuil. Codecov commente automatiquement les PR avec le diff de couverture, montrant quelles lignes ont changé et comment cela a affecté le pourcentage global. Si la couverture a baissé, la PR est bloquée jusqu’à ce que des tests supplémentaires soient écrits.
# GitHub Actions — téléchargement de couverture vers Codecov
- name: Run Tests with Coverage
run: ./gradlew testDebugUnitTest jacocoTestReport
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
files: ./app/build/reports/jacoco/jacocoTestReport.xml
flags: unittests
fail_ci_if_error: true
- name: Check Coverage Threshold
run: |
coverage=$(grep -oP 'branchCoverage="\K[0-9.]+' report.xml)
if (( $(echo "$coverage < 80" | bc -l) )); then
echo "Coverage $coverage% is below 80% threshold"
exit 1
fi
Les rapports HTML de JaCoCo et XCCov contiennent une surbrillance visuelle de la couverture : vert — lignes exécutées, rouge — non exécutées. SonarQube montre en plus la couverture au niveau du fichier, de la classe, de la méthode et de la ligne, ainsi que l’historique des changements de couverture par sprints. Cela aide à prendre des décisions sur le refactoring et l’ajout de tests.
Questions fréquentes
Pour les projets mobiles, une couverture de 70–80 % pour la logique métier et de 50–60 % pour les composants d’interface est considérée comme bonne. Au-dessus de 80 %, les coûts des tests commencent à dépasser les bénéfices. Il est important de se rappeler que le pourcentage n’est pas un objectif mais un indicateur, et différents modules peuvent avoir différents niveaux cibles.
Line Coverage montre combien de lignes de code ont été exécutées. Branch Coverage montre combien de ramifications (if-else, switch) ont été testées. Une ligne avec if peut être exécutée, mais seule la branche true peut avoir été testée, pas la false. Branch Coverage est plus stricte et révèle plus de scénarios manqués.
Dans le CI/CD, la couverture est intégrée via un Quality Gate : le build est bloqué si la couverture est inférieure au seuil. Pour Android, on utilise JaCoCo + SonarQube ; pour iOS — xcodebuild -enableCodeCoverage avec analyse de .xccovreport. GitHub Actions dispose d’actions prêtes pour Codecov.
Oui, JaCoCo prend en charge Jetpack Compose via le mécanisme standard de couverture JVM. Cependant, le code Compose contient de nombreuses expressions lambda générées que JaCoCo peut ne pas couvrir complètement. Il est recommandé d’exclure le code Compose généré du rapport via des filtres.
La fausse couverture se produit lorsqu’un test exécute du code mais ne vérifie pas le résultat. Solution : écrire des assertions pour chaque scénario important, utiliser le mutation testing (Pitest) pour vérifier la qualité des tests, analyser non seulement le pourcentage mais aussi quelles branches sont couvertes.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi