Setelah menulis test berminggu-minggu, pertanyaan yang pasti muncul: “apakah test saya sudah cukup?”. Kita tidak bisa menjawab dengan membaca semua test satu per satu — proyek nyata punya ratusan fungsi. Code coverage memberi angka awal: persentase baris kode produksi yang pernah dieksekusi saat test berjalan. Angka ini bukan ukuran kebenaran, tetapi kompas yang menunjukkan wilayah kode yang belum pernah tersentuh test sama sekali. Pada Chapter ini kita menjalankan pengukuran dengan pytest-cov dan coverage, lalu membedah cara membaca dan menafsirkan hasilnya.
Apa yang Diukur (dan yang Tidak) #
| Coverage mengukur | Coverage tidak mengukur |
|---|---|
| Baris yang pernah dieksekusi saat test berjalan | apakah assertion pada baris itu benar |
| Fungsi yang tak pernah dipanggil test | apakah test memeriksa perilaku yang tepat |
Cabang if yang tak pernah dilalui | kebenaran logika bisnis secara keseluruhan |
Sebuah baris yang dieksekusi tanpa assertion apa pun tetap dihitung tercakup. Itulah sebabnya angka coverage yang tinggi bukan jaminan bebas bug — ia hanya menjamin tidak ada wilayah yang sepenuhnya gelap.
Mengukur dengan pytest-cov #
Plugin pytest-cov menyematkan pengukuran langsung ke perintah pytest. Kita uji kalkulator.py dengan test yang sengaja hanya menyentuh tambah() dan jalur normal bagi():
from kalkulator import tambah, bagi
def test_tambah_dua_angka():
assert tambah(2, 3) == 5
def test_bagi_dua_angka():
assert bagi(10, 4) == 2.5Jalankan dengan flag --cov:
python3 -m pytest -q --cov=kalkulator --cov-report=term-missingOutput yang Dihasilkan:
.. [100%]
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.12.15-final-0 _______________
Name Stmts Miss Cover Missing
---------------------------------------------
kalkulator.py 13 4 69% 9-10, 18, 23
---------------------------------------------
TOTAL 13 4 69%
2 passed in 0.07sCara membaca tabelnya:
- Kolom
Stmts: jumlah statement yang bisa dieksekusi padakalkulator.py. - Kolom
Miss: empat baris tidak pernah dijalankan test. - Kolom
Missing: lokasi persisnya — baris9-10(constructorPembagianNolError), baris18(isikurang()), dan baris23(raisedi dalambagi()). Jalur error pembagian nol yang kita uji pada Chapter Testing Exceptions memang tidak diuji di file ini.
Alternatif: coverage sebagai CLI #
Bila proyek belum memasang plugin pytest, tool coverage bisa dipakai berdiri sendiri:
coverage run -m pytest -qOutput yang Dihasilkan:
.. [100%]
2 passed in 0.01sData terkumpul di berkas .coverage; laporan dibuka setelahnya:
coverage report -mOutput yang Dihasilkan:
Name Stmts Miss Cover Missing
------------------------------------------------
kalkulator.py 13 4 69% 9-10, 18, 23
test_sebagian.py 5 0 100%
------------------------------------------------
TOTAL 18 4 78%Perhatikan bahwa coverage report juga menghitung file test sendiri — angka total jadi campuran kode produksi dan test. Perintah --cov=kalkulator pada pytest-cov lebih tepat menyasar module produksi; gunakan --cov=. untuk mengukur seluruh proyek bila memang itu tujuannya.
Mitos 100 Persen #
Mengejar 100% coverage terasa memuaskan, tetapi dua bahaya mengintai:
- Assertion kosong. Coverage naik hanya karena baris dieksekusi, sehingga tim tertekan menambah test yang memanggil fungsi tanpa memeriksa hasil. Angka mengkilap, verifikasi tipis.
- Test rapuh untuk kode mati. Beberapa baris (fallback darurat, guard lama) sulit diuji karena butuh kondisi ekstrem. Memaksakan 100% kerap menghasilkan test yang rumit demi baris yang tidak penting.
Panduan yang lebih sehat untuk menafsirkan coverage:
- Gunakan coverage untuk menemukan wilayah gelap — kode besar yang belum tersentuh test sama sekali.
- Prioritaskan wilayah berisiko tinggi: logika bisnis inti dan jalur error, bukan getter/setter.
- Tetapkan target menurut konteks (misalnya 80–90% untuk library publik), bukan angka mutlak untuk semua proyek.
Coverage menjawab “apa yang terlewat”. Kualitas kode itu sendiri — kebiasaan penulisan yang rapi dan konsisten — dijaga oleh linter dan formatter pada Chapter Linting dan Formatting.