Code Coverage (code dekking) is een metriek die laat zien welk percentage van de broncode van een applicatie wordt uitgevoerd tijdens het testen. Het helpt om de kwaliteit van tests te bepalen, ongeteste gedeelten te identificeren en prioriteiten te stellen voor het schrijven van nieuwe tests. Volgens Atlassian, 2025 is het optimale dekkingsniveau 70–80% — boven deze drempel beginnen de kosten van tests de voordelen te overschrijden.
Belangrijkste punten
Code Coverage (code dekking) is een kwantitatieve metriek die bepaalt welk deel van de broncode van een applicatie is uitgevoerd tijdens tests. Het wordt uitgedrukt in procenten en berekend als de verhouding van het aantal uitgevoerde regels/takken tot het totaal. Hoge dekking garandeert niet de afwezigheid van bugs, maar vermindert het risico op gemiste fouten.
Codedekking helpt het team: ongeteste gedeelten van de code te vinden, beslissingen te nemen over prioriteiten voor het schrijven van tests, de dynamiek van testkwaliteit in CI/CD te volgen. In mobiele ontwikkeling is dekking vooral belangrijk voor bedrijfslogica, gegevensmodellen en repositories — lagen waar de kans op fouten het grootst is.
Een veelvoorkomende mythe: „100% dekking = ideale kwaliteit“. In de praktijk wordt 100% dekking uiterst zelden bereikt en vaak ten koste van oppervlakkige tests. Effectieve dekking is geen race om het percentage, maar strategische dekking van kritieke paden en randvoorwaarden. Dekking zegt niets over de kwaliteit van de tests zelf: een test kan slagen maar niet de juistheid van het resultaat controleren.
Er bestaan verschillende Code Coverage metrieken, die elk verschillende aspecten van testen meten. Line coverage (regeldekking) is de eenvoudigste metriek die het percentage uitgevoerde coderegels weergeeft. Branch coverage (takdekking) meet welke if-else en switch vertakkingen zijn getest.
Line coverage telt elke regel broncode als uitgevoerd of niet. Als een regel een voorwaardelijke operator of lus bevat, wordt de regel als uitgevoerd beschouwd als de besturing de regel heeft bereikt, zelfs als niet alle takken zijn verwerkt. Dit is de minst strikte metriek, maar het meest begrijpelijk voor visuele beoordeling.
Branch coverage beoordeelt of alle mogelijke vertakkingen in de code zijn getest. Voor elke if-else worden beide takken in aanmerking genomen: true en false. Voor switch — elke case. Branch coverage wordt als een strengere metriek beschouwd dan line coverage en detecteert vaker ongeteste scenario’s.
| Metriek | Wat het meet | Moeilijkheidsgraad |
|---|---|---|
| Line | Percentage uitgevoerde coderegels | Laag |
| Branch | Percentage uitgevoerde vertakkingen (if/else, switch) | Gemiddeld |
| Function | Percentage aangeroepen functies en methoden | Laag |
| Condition | Percentage logische subexpressies (&&, ||) | Hoog |
Path coverage — de strengste metriek die verificatie van alle mogelijke combinaties van vertakkingen in een functie vereist. In de praktijk wordt path coverage zelden gebruikt vanwege de exponentiële groei van het aantal combinaties: een functie met 10 vertakkingen heeft 1024 mogelijke paden.
In mobiele ontwikkeling worden verschillende tools gebruikt voor het meten van Code Coverage, afhankelijk van het platform. Voor Android is de standaard JaCoCo (Java Code Coverage), die integreert met Gradle en zowel unit tests als instrumentele tests ondersteunt. Voor iOS wordt XCCov gebruikt, ingebouwd in Xcode.
JaCoCo genereert rapporten in HTML, XML en CSV-formaten. Het HTML-rapport markeert regels visueel: groen — uitgevoerd, rood — overgeslagen, geel — gedeeltelijk uitgevoerd. Het XML-rapport is compatibel met SonarQube en andere code-analysesystemen. JaCoCo ondersteunt het filteren van klassen: gegenereerde code, databinding en BuildConfig kunnen worden uitgesloten.
// build.gradle — JaCoCo configuratie
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
// JaCoCo rapport aanmaken
task jacocoTestReport(type: JacocoReport) {
dependsOn 'testDebugUnitTest'
reports {
xml.enabled = true
html.enabled = true
}
}
XCCov — de ingebouwde tool van Xcode voor het meten van codedekking. Het wordt ingeschakeld via Gather coverage data in het testschema. XCCov ondersteunt dekking voor Swift en Objective-C, genereert rapporten in .xccovreport en integreert met CI via xcodebuild -enableCodeCoverage YES. Gegevens worden in de console weergegeven en kunnen naar JSON worden geëxporteerd.
Voor gecentraliseerde monitoring van dekking worden platforms gebruikt: SonarQube (codekwaliteitsanalyse + dekking), Codecov en Coveralls. Deze diensten aggregeren gegevens van JaCoCo en XCCov, tonen trends, Quality Gate en integratie met GitHub/GitLab via PR-reacties.
Het verhogen van Code Coverage vereist een systematische aanpak: niet „de percentages najagen“, maar risico’s afdekken. De eerste stap is het analyseren van het JaCoCo- of XCCov-rapport — identificatie van rode (niet-gedekte) klassen. Prioriteit: bedrijfslogica → repositories → ViewModel → UI-componenten.
Test-Driven Development (TDD) zorgt automatisch voor hoge dekking, omdat tests vóór de implementatie worden geschreven. Proces: rood (schrijf een test die faalt) → groen (schrijf minimale code) → refactoren. TDD disciplineert de ontwikkelaar door randgevallen en uitzonderlijke situaties te dekken die vaak zonder tests blijven.
Eén geparametriseerde test vervangt tientallen gewone tests. JUnit en XCTest ondersteunen parametrisatie: @ParameterizedTest in JUnit 5, XCTestCase met testPerformanceExample in XCTest. Parametrisatie maakt het mogelijk om meerdere invoergegevens te controleren zonder code te dupliceren, wat de tak- en voorwaardendekking aanzienlijk uitbreidt.
// Geparametriseerde test in Kotlin met 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)
}
De meest voorkomende fout — jagen op het percentage zonder analyse van de testkwaliteit. Het team begint tests te schrijven om het testen: getters en setters controleren, dekking op verschillende niveaus dupliceren, triviale methoden testen. Dit geeft een hoog percentage, maar verhoogt de werkelijke kwaliteit niet.
Hoge Code Coverage kan de valse indruk wekken dat de applicatie goed is getest. Een test kan een coderegel uitvoeren maar de juistheid van het resultaat niet controleren. Bijvoorbeeld: een test roept een kortingsberekeningsmethode aan, maar controleert het bedrag niet — de regel is uitgevoerd, de dekking stijgt, maar de bug wordt niet gevonden.
Een typische fout — alleen het „gelukkige pad“ (happy path) testen en randgevallen negeren: lege lijsten, null-waarden, maximum getallen, onjuiste formaten. De meeste bugs ontstaan precies op grenzen en uitzonderingen. Branch coverage helpt gemiste takken te detecteren, maar garandeert geen controle van grenswaarden.
Mutation Testing is een methode om de kwaliteit van tests te beoordelen waarbij mutaties (kunstmatige fouten) in de broncode worden geïntroduceerd en wordt gecontroleerd of de tests falen. Pitest — een populaire mutation testing tool voor Java en Kotlin. Als tests niet falen op een mutatie — betekent dit dat ze die voorwaarde niet controleren.
Pitest creëert mutanten — gewijzigde kopieën van de broncode, waarin bijvoorbeeld > is vervangen door >=, true door false, of een methodeaanroep is verwijderd. Vervolgens worden voor elke mutant de tests uitgevoerd. Als de tests slagen — heeft de mutant overleefd, wat betekent dat de tests dit scenario niet dekken. Als de tests falen — is de mutant gedood, de test is correct.
// build.gradle — Pitest configuratie
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 ondersteunt vele soorten mutaties: wijziging van voorwaardelijke operatoren (== → !=, < → <=), verwijdering van methodeaanroepen, vervanging van retourwaarden (true → false), wijziging van rekenkundige bewerkingen (+ → -), mutatie van incrementen (i++ → i--). Hoe meer soorten mutaties door tests worden gedood, hoe betrouwbaarder de testsuite.
Het doel mutation score — 80% en hoger. Dit betekent dat 80% van de kunstmatige fouten door tests zijn gedetecteerd. Codedekking (Code Coverage) van 90% garandeert niet dat tests fouten vinden — mutation testing geeft een objectievere beoordeling. Pitest kan in CI worden geïntegreerd als Quality Gate, waarbij de build wordt geblokkeerd wanneer de mutation score onder de drempel zakt.
Voor automatische controle van Code Coverage in CI/CD worden Quality Gates gebruikt — drempelwaarden, bij overtreding waarvan de build als onstabiel wordt gemarkeerd of wordt afgewezen. SonarQube maakt het mogelijk een Quality Gate in te stellen op basis van een combinatie van metrieken: dekking (≥80%), aantal bugs, kwetsbaarheden en gedupliceerde code.
In GitHub Actions wordt Code Coverage geïntegreerd via actiestappen: tests uitvoeren met dekking → rapport uploaden naar Codecov → drempel controleren. Codecov reageert automatisch op de PR met een dekkingsdiff, laat zien welke regels zijn gewijzigd en hoe dit het totale percentage heeft beïnvloed. Als de dekking is gedaald — wordt de PR geblokkeerd tot het schrijven van aanvullende tests.
# GitHub Actions — dekking uploaden naar 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
HTML-rapporten van JaCoCo en XCCov bevatten visuele markering van dekking: groen — uitgevoerde regels, rood — niet-uitgevoerde. SonarQube toont daarnaast dekking op bestands-, klasse-, methode- en regelniveau, evenals de geschiedenis van dekkingsveranderingen per sprint. Dit helpt bij het nemen van beslissingen over refactoring en het toevoegen van tests.
Veelgestelde vragen
Voor mobiele projecten wordt een dekking van 70–80% voor bedrijfslogica en 50–60% voor UI-componenten als goed beschouwd. Boven 80% beginnen de testkosten de voordelen te overschrijden. Het is belangrijk te onthouden dat het percentage geen doel is, maar een indicator, en verschillende modules kunnen verschillende doelniveaus hebben.
Line Coverage laat zien hoeveel coderegels zijn uitgevoerd. Branch Coverage — hoeveel vertakkingen (if-else, switch) zijn getest. Een regel met if kan worden uitgevoerd, maar de true-tak getest en de false-tak niet. Branch Coverage is strenger en detecteert meer gemiste scenario’s.
In CI/CD wordt dekking geïntegreerd via Quality Gate: de build wordt geblokkeerd als de dekking onder de drempel ligt. Voor Android wordt JaCoCo + SonarQube gebruikt, voor iOS — xcodebuild -enableCodeCoverage met parsing van .xccovreport. GitHub Actions heeft kant-en-klare actions voor Codecov.
Ja, JaCoCo ondersteunt Jetpack Compose via het standaard JVM-dekkingsmechanisme. Echter, Compose-code bevat veel gegenereerde lambda-expressies die JaCoCo mogelijk niet volledig kan dekken. Het wordt aanbevolen gegenereerde compose-code uit het rapport te filteren.
Valse dekking ontstaat wanneer een test code uitvoert maar het resultaat niet controleert. Oplossing: schrijf assert-controles voor elk belangrijk scenario, gebruik mutation testing (Pitest) om de testkwaliteit te controleren, analyseer niet alleen het percentage maar ook welke takken worden gedekt.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook