Code Coverage (cakupan kode) adalah metrik yang menunjukkan berapa persen kode sumber aplikasi yang dieksekusi selama pengujian. Ini membantu menentukan kualitas tes, mengidentifikasi area yang belum diuji, dan memprioritaskan penulisan tes baru. Menurut Atlassian, 2025, tingkat cakupan optimal adalah 70–80% — di atas ambang ini, biaya pengujian mulai melebihi manfaatnya.
Poin Penting
Code Coverage (cakupan kode) adalah metrik kuantitatif yang menentukan bagian mana dari kode sumber aplikasi yang telah dieksekusi selama pengujian. Ini dinyatakan dalam persentase dan dihitung sebagai rasio jumlah baris/cabang yang dieksekusi terhadap total. Cakupan tinggi tidak menjamin tidak adanya bug, tetapi mengurangi risiko kesalahan yang terlewatkan.
Cakupan kode membantu tim: menemukan area yang belum diuji dalam kode, membuat keputusan tentang prioritas penulisan tes, melacak dinamika kualitas pengujian di CI/CD. Dalam pengembangan mobile, cakupan sangat penting untuk logika bisnis, model data, dan repositori — lapisan di mana probabilitas kesalahan paling tinggi.
Mitos yang umum: “100% cakupan = kualitas ideal”. Dalam praktiknya, cakupan 100% sangat jarang dicapai dan seringkali dengan harga tes yang dangkal. Cakupan efektif bukanlah perlombaan untuk persentase, tetapi cakupan strategis dari jalur kritis dan kondisi batas. Cakupan tidak mengatakan apa-apa tentang kualitas tes itu sendiri: sebuah tes mungkin lulus tetapi tidak memeriksa kebenaran hasil.
Ada beberapa metrik Code Coverage, yang masing-masing mengukur aspek pengujian yang berbeda. Line coverage (cakupan baris) — metrik paling sederhana yang menunjukkan persentase baris kode yang dieksekusi. Branch coverage (cakupan cabang) mengukur cabang if-else dan switch mana yang telah diuji.
Line coverage menghitung setiap baris kode sumber sebagai dieksekusi atau tidak. Jika dalam satu baris terdapat operator kondisional atau perulangan, baris tersebut dianggap dieksekusi jika kontrol telah mencapainya, bahkan jika tidak semua cabang diproses. Ini adalah metrik paling tidak ketat, tetapi paling mudah dipahami untuk penilaian visual.
Branch coverage mengevaluasi apakah semua cabang yang mungkin dalam kode telah diuji. Untuk setiap if-else, kedua cabang diperhitungkan: true dan false. Untuk switch — setiap case. Branch coverage dianggap sebagai metrik yang lebih ketat daripada line coverage dan lebih sering mendeteksi skenario yang belum diuji.
| Metrik | Apa yang diukur | Tingkat kesulitan |
|---|---|---|
| Line | Persentase baris kode yang dieksekusi | Rendah |
| Branch | Persentase cabang yang dieksekusi (if/else, switch) | Sedang |
| Function | Persentase fungsi dan metode yang dipanggil | Rendah |
| Condition | Persentase sub-ekspresi logis (&&, ||) | Tinggi |
Path coverage — metrik paling ketat yang memerlukan pemeriksaan semua kombinasi cabang yang mungkin dalam suatu fungsi. Dalam praktiknya, path coverage jarang digunakan karena pertumbuhan eksponensial jumlah kombinasi: fungsi dengan 10 cabang memiliki 1024 jalur yang mungkin.
Dalam pengembangan mobile, berbagai alat digunakan untuk mengukur Code Coverage tergantung pada platformnya. Untuk Android, standarnya adalah JaCoCo (Java Code Coverage), yang terintegrasi dengan Gradle dan mendukung baik tes unit maupun tes instrumental. Untuk iOS, digunakan XCCov yang tertanam di Xcode.
JaCoCo menghasilkan laporan dalam format HTML, XML, dan CSV. Laporan HTML secara visual menyorot baris: hijau — dieksekusi, merah — dilewati, kuning — dieksekusi sebagian. Laporan XML kompatibel dengan SonarQube dan sistem analisis kode lainnya. JaCoCo mendukung pemfilteran kelas: kode yang dihasilkan, databinding, BuildConfig dapat dikecualikan.
// build.gradle — konfigurasi JaCoCo
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
// Membuat laporan JaCoCo
task jacocoTestReport(type: JacocoReport) {
dependsOn 'testDebugUnitTest'
reports {
xml.enabled = true
html.enabled = true
}
}
XCCov — alat bawaan Xcode untuk mengukur cakupan kode. Ini diaktifkan melalui Gather coverage data dalam skema pengujian. XCCov mendukung cakupan untuk Swift dan Objective-C, menghasilkan laporan dalam .xccovreport dan terintegrasi dengan CI melalui xcodebuild -enableCodeCoverage YES. Data ditampilkan di konsol dan dapat diekspor ke JSON.
Untuk pemantauan cakupan terpusat, digunakan platform: SonarQube (analisis kualitas kode + cakupan), Codecov dan Coveralls. Layanan ini mengumpulkan data dari JaCoCo dan XCCov, menampilkan tren, Quality Gate, dan integrasi dengan GitHub/GitLab melalui komentar PR.
Meningkatkan Code Coverage memerlukan pendekatan sistematis: bukan “mengejar persentase”, tetapi menutup risiko. Langkah pertama adalah menganalisis laporan JaCoCo atau XCCov — mengidentifikasi kelas merah (tidak tercakup). Prioritas: logika bisnis → repositori → ViewModel → komponen UI.
Test-Driven Development (TDD) secara otomatis memastikan cakupan tinggi, karena tes ditulis sebelum implementasi. Proses: merah (tulis tes yang gagal) → hijau (tulis kode minimal) → refactoring. TDD mendisiplinkan pengembang, memaksa untuk mencakup kasus batas dan situasi luar biasa yang seringkali tanpa tes.
Satu tes terparameterisasi menggantikan puluhan tes biasa. JUnit dan XCTest mendukung parameterisasi: @ParameterizedTest di JUnit 5, XCTestCase dengan testPerformanceExample di XCTest. Parameterisasi memungkinkan pemeriksaan banyak data masukan tanpa menduplikasi kode, yang secara signifikan memperluas cakupan cabang dan kondisi.
// Tes terparameterisasi di Kotlin dengan 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)
}
Kesalahan paling umum — berlomba mengejar persentase tanpa menganalisis kualitas tes. Tim mulai menulis tes demi tes: memeriksa getter dan setter, menduplikasi cakupan di berbagai level, menguji metode sepele. Ini memberikan persentase tinggi tetapi tidak meningkatkan kualitas sebenarnya.
Code Coverage yang tinggi dapat menciptakan kesan palsu bahwa aplikasi telah diuji dengan baik. Sebuah tes mungkin mengeksekusi baris kode tetapi tidak memeriksa kebenaran hasil. Contoh: tes memanggil metode perhitungan diskon, tetapi tidak memeriksa jumlahnya — baris dieksekusi, cakupan meningkat, tetapi bug tidak ditemukan.
Kesalahan tipikal — menguji hanya “jalur bahagia” (happy path) dan mengabaikan kasus batas: daftar kosong, nilai null, angka maksimum, format yang salah. Sebagian besar bug terjadi tepat di batas dan pengecualian. Branch coverage membantu mendeteksi cabang yang terlewat, tetapi tidak menjamin pemeriksaan nilai batas.
Mutation Testing adalah metode evaluasi kualitas tes di mana mutasi (kesalahan buatan) dimasukkan ke dalam kode sumber dan diperiksa apakah tes akan gagal. Pitest — alat mutation testing populer untuk Java dan Kotlin. Jika tes tidak gagal pada mutasi — berarti mereka tidak memeriksa kondisi tersebut.
Pitest menciptakan mutan — salinan kode sumber yang dimodifikasi, di mana, misalnya, > diganti dengan >=, true dengan false, atau panggilan metode dihapus. Kemudian untuk setiap mutan, tes dijalankan. Jika tes lulus — mutan selamat, berarti tes tidak mencakup skenario ini. Jika tes gagal — mutan terbunuh, tes benar.
// build.gradle — konfigurasi 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 mendukung banyak jenis mutasi: perubahan operator kondisional (== → !=, < → <=), penghapusan panggilan metode, penggantian nilai kembali (true → false), perubahan operasi aritmatika (+ → -), mutasi increment (i++ → i--). Semakin banyak jenis mutasi yang dibunuh oleh tes, semakin andal rangkaian tes tersebut.
Target mutation score — 80% dan lebih tinggi. Ini berarti 80% kesalahan buatan telah terdeteksi oleh tes. Cakupan kode (Code Coverage) 90% tidak menjamin bahwa tes menemukan kesalahan — mutation testing memberikan penilaian yang lebih objektif. Pitest dapat diintegrasikan ke dalam CI sebagai Quality Gate, memblokir build ketika mutation score turun di bawah ambang batas.
Untuk kontrol otomatis Code Coverage di CI/CD, digunakan Quality Gates — nilai ambang, yang jika dilanggar, build akan ditandai sebagai tidak stabil atau ditolak. SonarQube memungkinkan konfigurasi Quality Gate berdasarkan kombinasi metrik: cakupan (≥80%), jumlah bug, kerentanan, dan kode duplikat.
Di GitHub Actions, Code Coverage diintegrasikan melalui langkah-langkah action: menjalankan tes dengan cakupan → mengunggah laporan ke Codecov → memeriksa ambang batas. Codecov secara otomatis mengomentari PR dengan diff cakupan, menunjukkan baris mana yang berubah dan bagaimana hal itu mempengaruhi persentase keseluruhan. Jika cakupan turun — PR diblokir sampai tes tambahan ditulis.
# GitHub Actions — unggah cakupan ke 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
Laporan HTML JaCoCo dan XCCov berisi penyorotan visual cakupan: hijau — baris yang dieksekusi, merah — tidak dieksekusi. SonarQube juga menunjukkan cakupan di tingkat file, kelas, metode, dan baris, serta riwayat perubahan cakupan per sprint. Ini membantu dalam pengambilan keputusan tentang refactoring dan penambahan tes.
Pertanyaan Umum
Untuk proyek mobile, cakupan 70–80% untuk logika bisnis dan 50–60% untuk komponen UI dianggap baik. Di atas 80%, biaya pengujian mulai melebihi manfaat. Penting untuk diingat bahwa persentase bukanlah tujuan, melainkan indikator, dan modul yang berbeda mungkin memiliki tingkat target yang berbeda.
Line Coverage menunjukkan berapa banyak baris kode yang dieksekusi. Branch Coverage — berapa banyak cabang (if-else, switch) yang diuji. Baris dengan if mungkin dieksekusi, tetapi cabang true diuji dan false tidak. Branch Coverage lebih ketat dan mendeteksi lebih banyak skenario yang terlewat.
Di CI/CD, cakupan diintegrasikan melalui Quality Gate: build diblokir jika cakupan di bawah ambang batas. Untuk Android digunakan JaCoCo + SonarQube, untuk iOS — xcodebuild -enableCodeCoverage dengan parsing .xccovreport. GitHub Actions memiliki action siap pakai untuk Codecov.
Ya, JaCoCo mendukung Jetpack Compose melalui mekanisme cakupan JVM standar. Namun, kode Compose mengandung banyak ekspresi lambda yang dihasilkan yang mungkin tidak sepenuhnya dicakup oleh JaCoCo. Disarankan untuk mengecualikan kode compose yang dihasilkan dari laporan melalui filter.
Cakupan palsu terjadi ketika tes mengeksekusi kode tetapi tidak memeriksa hasilnya. Solusi: tulis pemeriksaan assert untuk setiap skenario penting, gunakan mutation testing (Pitest) untuk memeriksa kualitas tes, analisis tidak hanya persentase tetapi juga cabang mana yang tercakup.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga