Code Coverage vs Functional Coverage
Gün 5: Arayüzler, Assertion ve Coverage | "Yeterince test ettim mi?" sorusuna iki farklı cevap — ve DO-254 projelerinde bu cevapların neden hayati olduğu
Bu derste doğrulama dünyasının en çok karıştırılan iki kavramını, code coverage ve functional coverage, sıfırdan ve sezgisel örneklerle öğreneceksiniz. Dersin ikinci yarısında havacılık donanımı standardı DO-254 projelerinde bu iki ölçütün neden "güzel olsa iyi olur" değil, sertifikasyon için zorunlu kanıt olduğunu göreceksiniz. Dersin sonundaki Coverage Simülatörü'nde ise testleri kendiniz koşup satır sayaçlarının nasıl arttığını, eksik (missing) satırların nasıl oluştuğunu ve kapsamın DO-254 seviyesinde nasıl kapatıldığını uygulamalı olarak göreceksiniz.
Önce Bir Soru: "Test Ettim" Ne Demek?
Yeni bir işe başladığınızı ve ilk göreviniz olarak size bir ALU tasarımının doğrulanması verildiğini düşünün. Birkaç test yazdınız, hepsi geçti. Takım liderinize "bitti" dediniz. İlk sorusu şu olacak:
"Neyi test ettin? Ne kadarını test ettin? Nereden biliyorsun?"
Bu üç soru, bu dersin tamamıdır. "Testler geçti" cümlesi tek başına hiçbir şey ifade etmez; çünkü hiç çalıştırılmamış bir kod satırında bug varsa, testler yine de geçer. Hiç denenmemiş bir senaryo yanlış çalışıyorsa, testler yine de geçer.
Coverage, işte bu "nereden biliyorsun?" sorusunun sayısal cevabıdır. İki farklı açıdan bakar:
| Soru | Cevabı veren ölçüt | Bakış açısı |
|---|---|---|
| "Yazdığım kodun ne kadarı çalıştı?" | Code coverage | Tasarımın içinden (white-box) |
| "Spesifikasyondaki senaryoların ne kadarını denedim?" | Functional coverage | Tasarımın dışından (black-box) |
İkisi birbirinin yerine geçmez. Neden geçmediğini anlamak, bu dersin özüdür.
Bir Benzetme: Sürücü Kursu
Ehliyet sınavına hazırlanan bir öğrenci düşünün.
- Code coverage, eğitmenin "aracın bütün parçalarını kullandın mı?" diye sormasıdır: Gaz pedalına bastın mı? Frene? Debriyaja? Sol sinyale? Sağ sinyale? El frenini çektin mi? Her parça en az bir kez kullanıldıysa code coverage %100'dür.
- Functional coverage, eğitmenin "trafikte karşılaşacağın durumları yaşadın mı?" diye sormasıdır: Yokuşta kalkış yaptın mı? Yağmurda sürdün mü? Gece sürdün mü? Yaya geçidinde durdun mu? Park ettin mi?
Şimdi kritik nokta: Öğrenci bütün pedalları ve kontrolleri kullanmış olabilir (code coverage %100), ama hiç yokuşta kalkış yapmamış olabilir (functional coverage eksik). Tersine, yokuşta kalkış yapmış olabilir ama aracın sağ sinyalini hiç kullanmamış olabilir.
İkisi de tam olmadan "bu kişi araba kullanabilir" diyemezsiniz. Tasarım doğrulamada da durum aynıdır.
Code Coverage: Kodun İçine Bakmak
Code coverage, simülatörün otomatik olarak topladığı bir ölçüttür. Siz hiçbir ek kod yazmazsınız; simülatöre "coverage topla" dersiniz (örneğin -coverage all benzeri bir seçenekle), o da RTL'deki her yapıyı izleyip "bu çalıştı, bu çalışmadı" diye işaretler.
Birkaç alt türü vardır. Her biri aynı koda farklı bir mercekle bakar:
1. Statement (Line) Coverage
En basit tür. "Her ifade en az bir kez çalıştı mı?"
always_ff @(posedge clk) begin
if (rst) count <= 0; // Satır A
else if (en) count <= count + 1; // Satır B
else count <= count; // Satır C
end
Testinizde rst hiç 1 olmadıysa, Satır A hiç çalışmamıştır. Statement coverage bunu size "Satır A: 0 hit" diye gösterir.
2. Branch Coverage
"Her if/else branch'i, her case branch'i hem doğru hem yanlış yönde alındı mı?"
Statement coverage ile farkı şurada ortaya çıkar:
if (valid) data_out <= data_in;
// else yok!
Burada else branch'i olmadığı için statement coverage valid = 1 olduğunda %100 olur. Ama branch coverage, valid = 0 durumunun (yani "atlama" branch'inin) hiç test edilmediğini gösterir. Yazılmamış else, test edilmemiş bir davranıştır.
3. Condition / Expression Coverage
Bir if içindeki her condition teriminin sonucu tek başına etkilediği görüldü mü?
if (a && b) fire <= 1;
Branch coverage için bu if'in bir kez doğru, bir kez yanlış olması yeter. Ama a=1,b=1 (doğru) ve a=0,b=0 (yanlış) denemeleri, b'nin tek başına sonucu değiştirdiğini hiç göstermez. Belki de kodda yanlışlıkla a && b yerine a yazılsaydı testler yine geçerdi. Condition coverage, a=1,b=0 ve a=0,b=1 gibi durumların da denenmesini ister.
Bu tür, DO-254'te özellikle önemlidir; birazdan göreceğiz.
4. Toggle Coverage
"Her sinyal/bit en az bir kez 0→1 ve 1→0 toggle yaptı mı?"
32-bit bir veri yolunun üst 8 biti hiç değişmediyse, muhtemelen o bitlere giden yolu test etmediniz — ya da o bitler tasarımda gerçekten bağlı değil (ki bu da bir bug olabilir).
5. FSM Coverage
"FSM'in her state'i ziyaret edildi mi? Her transition'ı alındı mı?"
IDLE → BUSY → DONE → IDLE döngüsü çalışmış ama BUSY → ERROR transition'ı hiç alınmamışsa, hata yolu test edilmemiştir.
Alt türlerin karşılaştırması
| Tür | Sorduğu soru | Güçlü yanı | Zayıf yanı |
|---|---|---|---|
| Statement | Bu satır çalıştı mı? | Çok basit, hızlı anlaşılır | else'siz if'leri kaçırır |
| Branch | Her branch alındı mı? | Kontrol akışını görür | Condition içini görmez |
| Condition | Her condition terimi etkili oldu mu? | Mantık hatalarını yakalar | Toplaması pahalı, raporu uzun |
| Toggle | Her bit değişti mi? | Bağlantı hatalarını bulur | Çok gürültülü olabilir |
| FSM | Her state/transition alındı mı? | Kontrol mantığını doğrular | Sadece FSM olarak tanınan yapılarda |
Code coverage'ın en büyük sınırı
Şu kodu düşünün:
// Spesifikasyon: sonuc = a + b
assign sonuc = a - b; // BUG! Toplama yerine çıkarma
Bu satır her simülasyonda çalışır. Statement coverage %100. Branch yok, condition yok. Toggle büyük ihtimalle %100. Ama tasarım yanlış.
Code coverage size "kodun çalıştı" der; "kodun doğru şeyi yaptı" demez. Bu yüzden code coverage, hiçbir zaman doğruluk ölçütü değildir. Yalnızca "test edilmemiş bölge kaldı mı?" sorusunu cevaplar. Ayrıca spesifikasyonda olup da kodda hiç yazılmamış bir özelliği (eksik özellik) göremez; çünkü var olmayan bir satırın coverage'ı ölçülemez.
Functional Coverage: Spesifikasyona Bakmak
Functional coverage'ı simülatör sizin için otomatik toplamaz. Çünkü neyin "anlamlı senaryo" olduğunu yalnızca siz bilirsiniz; spesifikasyonu okuyan sizsiniz.
Süreç şöyle işler:
- Doğrulama planı (verification plan) yazarsınız. Spesifikasyondaki her gereksinimi "bunu nasıl test edeceğim?" sorusuyla eşlersiniz.
- Her gereksinim için ölçülebilir bir hedef tanımlarsınız: "Her ALU işlemi en az bir kez çalışmalı", "Taşma (overflow) bayrağı hem 0 hem 1 görülmeli", "Toplama işlemi sıfır operandla denenmiş olmalı".
- Bu hedefleri SystemVerilog'da
covergroup/coverpoint/binsolarak kodlarsınız. - Simülasyon koşar, bin'ler dolar, rapor "hangi senaryo kaç kez gerçekleşti" der.
covergroup alu_cg @(posedge clk iff valid);
op_cp : coverpoint op {
bins add = {ADD};
bins sub = {SUB};
bins mul = {MUL};
illegal_bins bad = default; // tanımsız opcode asla gelmemeli
}
ovf_cp : coverpoint overflow; // 0 ve 1 görülmeli
a_cp : coverpoint a {
bins zero = {0};
bins max = {'1};
bins mid = {[1:$-1]}; // $ = aralığın son değeri
}
op_x_ovf : cross op_cp, ovf_cp; // her işlemde taşma denenmiş mi?
endgroup
Rapor size şunu söyleyebilir:
op_cp.mul : 0 hit ← çarpma hiç test edilmedi!
op_x_ovf.sub/1 : 0 hit ← çıkarmada taşma hiç görülmedi!
Bu bilgiyi code coverage asla veremezdi. Çünkü MUL branch'i belki case içinde var ve branch coverage onu "alındı" diye işaretlemiş olabilir — ama taşma ile birlikte hiç denenmemiştir. Senaryoların kombinasyonunu ancak functional coverage görür.
Functional coverage'ın en büyük sınırı
Functional coverage, sizin yazdığınız kadar iyidir. Spesifikasyonda bir gereksinimi gözden kaçırdıysanız, ona covergroup yazmazsınız; o senaryo hiç ölçülmez ve rapor yine %100 der. Coverage modeli eksikse %100 sahte bir güven verir.
Bu yüzden functional coverage gözden geçirilmelidir (review). "Covergroup'lar spesifikasyonun tamamını temsil ediyor mu?" sorusu bir ekip sorusudur, tek kişilik değil.
İki Coverage Yan Yana
| Code Coverage | Functional Coverage | |
|---|---|---|
| Soru | Kodun ne kadarı çalıştı? | Spesifikasyonun ne kadarı denendi? |
| Kim tanımlar? | Simülatör, otomatik | Doğrulama mühendisi, elle |
| Kaynak | RTL kodu | Spesifikasyon / gereksinimler / doğrulama planı |
| Bakış | White-box (içeriden) | Black-box (dışarıdan) |
| %100 ne demek? | "Her statement/branch/condition en az bir kez koştu" | "Planladığım her senaryo en az bir kez gerçekleşti" |
| Göremediği şey | Yanlış yazılmış ama çalışan kod; eksik özellik | Plana yazılmayı unutulmuş senaryo |
| Maliyet | Düşük (bir seçenek açarsın) | Yüksek (düşünmek + kodlamak + gözden geçirmek) |
| Değeri | Ölü kod, erişilemeyen branch, unutulmuş test bulur | Eksik senaryo, kombinasyon boşluğu bulur |
| Doğrulamanın bittiğine karar verir mi? | Tek başına hayır | Tek başına hayır |
Son satır önemlidir. Sektörde yerleşik kural şudur:
Doğrulama, ancak code coverage ve functional coverage birlikte hedeflerine ulaştığında ve kalan her boşluk gerekçelendirildiğinde tamamlanmış sayılır.
Dört olası durum
İkisini bir arada düşününce dört senaryo çıkar. Her birinin size söylediği şey farklıdır:
| Code cov. | Functional cov. | Ne anlama gelir? | Ne yapmalı? |
|---|---|---|---|
| Yüksek | Yüksek | Hedefe yakınsınız | Kalan boşlukları kapat, gerekçele, bitir |
| Yüksek | Düşük | Kod koşuyor ama senaryolar eksik; testler "rastgele dolaşıyor" | Doğrulama planına dön, hedefli testler yaz |
| Düşük | Yüksek | Plan tamam ama kodda planda olmayan şeyler var | Ya spesifikasyon eksik, ya kodda fazlalık/ölü kod var — ikisi de bulgu! |
| Düşük | Düşük | Daha yolun başındasınız | Test yazmaya devam |
"Düşük code / yüksek functional" durumu, yeni başlayanların en çok şaşırdığı durumdur. Tüm senaryoları denediniz ama kodun bir kısmı hiç çalışmadı. Bu, kodda spesifikasyonda olmayan bir şey var demektir: belki tasarımcı "ileride lazım olur" diye bir özellik eklemiştir, belki eski bir özellik silinmemiştir, belki de spesifikasyon bir davranışı anlatmayı unutmuştur. Bu üç ihtimalin üçü de, özellikle güvenlik-kritik projelerde, ciddi bulgudur.
DO-254 Projelerinde Coverage: "Güzel Olur"dan "Zorunlu Kanıt"a
Buraya kadar anlattıklarımız her doğrulama projesi için geçerlidir. Şimdi havacılığa geçiyoruz.
DO-254 (Avrupa'da ED-80), uçaklarda kullanılan karmaşık elektronik donanımın (FPGA, ASIC, PLD) tasarım güvencesi için uygulanan standarttır. Bir FPGA'nın uçuş kontrol bilgisayarında, motor kontrolünde ya da iniş takımı mantığında kullanılabilmesi için sertifikasyon otoritesine (FAA, EASA, SHGM) "bu donanım güvenlidir" iddianızı kanıtlamanız gerekir.
DAL: "Ne kadar kritik?"
DO-254'te her donanım, bir hatasının yol açabileceği sonuca göre bir Tasarım Güvence Seviyesi (Design Assurance Level, DAL) alır:
| DAL | Hata sonucu | Örnek | Doğrulama beklentisi |
|---|---|---|---|
| A | Felaket (uçağın kaybı) | Birincil uçuş kontrolü | En sıkı; bağımsızlık + ileri doğrulama |
| B | Tehlikeli | Motor kontrol birimi | Çok sıkı; ileri doğrulama |
| C | Majör | Navigasyon ekranı | Gereksinim bazlı test |
| D | Minör | Kabin aydınlatma kontrolü | Temel |
| E | Etkisiz | Eğlence sistemi | Standart kapsamı dışında |
Seviye yükseldikçe sizden istenen kanıtın miktarı ve sıkılığı artar. DAL A ve B için DO-254'ün Ek B (Appendix B) bölümü, standart gereksinim bazlı testin üzerine ileri doğrulama yöntemleri ister. İşte coverage metrikleri tam burada sahneye çıkar.
Temel ilke: Gereksinim bazlı doğrulama
DO-254'ün omurgası şudur: Her test bir gereksinimden türetilir. Rastgele "hadi bir şeyler deneyelim" testleri sertifikasyon kanıtı değildir. Her gereksinim için:
- Gereksinim yazılır (ID'li, izlenebilir).
- Tasarım bu gereksinimi gerçekler.
- Test prosedürü bu gereksinimi doğrular.
- Test sonucu kaydedilir.
- İzlenebilirlik (traceability): Gereksinim ↔ Tasarım ↔ Test ↔ Sonuç zinciri belgelenir.
Buradaki "her gereksinim bir testle doğrulandı mı?" sorusuna requirements coverage denir ve bu, aslında functional coverage'ın sertifikasyon dünyasındaki karşılığıdır.
DO-254'te Code Coverage: Elemental Analysis
DAL A/B projelerinde otorite şunu sorar:
"Gereksinim bazlı testlerin, tasarımın her elemanını gerçekten uyardı mı? Tasarımda gereksinimlerle açıklanamayan bir parça var mı?"
Bu soruya cevap vermek için Ek B'deki elemental analysis yöntemi kullanılır. Pratikte sektörde kabul görmüş uygulama, bu analizin code coverage araçlarıyla yapılmasıdır:
- Gereksinim bazlı testler koşulur.
- Simülatör statement, branch, condition ve toggle coverage'ı toplar.
- Rapor incelenir: Coverage dışı kalan her statement, branch, condition tek tek ele alınır.
Coverage boşluğu (hole) bulunduğunda üç ihtimal vardır ve üçü de belgelenmek zorundadır:
| Boşluğun nedeni | Ne anlama gelir? | Yapılması gereken |
|---|---|---|
| Eksik test | Bir gereksinim var ama testi o kodu uyarmıyor | Test eksik → test yazılır |
| Eksik gereksinim | Kod var ama onu anlatan gereksinim yok | Spesifikasyon eksik → gereksinim eklenir veya kod kaldırılır |
| Ölü / erişilemeyen kod | Hiçbir girdi o kodu çalıştıramaz | Kod kaldırılır; kaldırılamıyorsa güvenlik etkisi analiz edilip gerekçelendirilir |
Ticari (non-safety) bir projede "%95 code coverage yeter, kalanı önemsiz" demek yaygındır. DO-254 DAL A/B'de böyle bir şey yoktur: %100'e ulaşırsınız ya da kalan her bir satır için yazılı, gözden geçirilmiş bir gerekçe sunarsınız. Otorite denetiminde (SOI audit) bu gerekçeler tek tek sorgulanabilir.
Neden condition coverage DO-254'te öne çıkar?
Daha önce gördüğümüz if (a && b) örneğini hatırlayın. Branch coverage bu if'i iki test ile "tam" sayıyordu, ama b'nin etkisini hiç kontrol etmiyordu.
Uçuş kritik bir donanımda, b örneğin "pilot onayı" sinyali olabilir. a && b yerine yanlışlıkla a yazılmış bir kod, branch coverage %100 ile sertifikasyona gidebilir. Bu kabul edilemez. Bu yüzden DAL A/B projelerinde, condition / expression coverage (bazı akışlarda "MC/DC benzeri" yaklaşım) beklenir. Yazılım dünyasında DO-178C'nin DAL A için istediği MC/DC (Modified Condition/Decision Coverage) ölçütü, donanım tarafında aynı felsefeyle "her koşulun sonucu bağımsız olarak etkilediği gösterilmeli" biçiminde karşılık bulur.
DO-254'te Functional Coverage: Gereksinimlerin Kanıtı
Code coverage "tasarımda fazlalık var mı?" sorusunu cevaplar. Functional coverage ise tam tersini: "gereksinimlerin tamamı gerçekten uyarıldı mı?"
DO-254 projelerinde functional coverage, doğrudan gereksinim izlenebilirliğine bağlanır:
- Her gereksinim (
REQ-HW-042: Watchdog 50 ms içinde reset üretmeli) için bir veya daha fazla coverage hedefi tanımlanır. - Covergroup'lar ve assertion'lar bu gereksinim ID'leriyle etiketlenir.
- Coverage raporu, "her gereksinimin kaç testle, hangi senaryolarda doğrulandığı" biçiminde bir izlenebilirlik matrisine dönüştürülür.
Şöyle düşünün: Sertifikasyon otoritesi size "REQ-HW-042'nin doğrulandığını göster" dediğinde, cevabınız "testler geçti" olamaz. Cevabınız şudur: "Bu gereksinim için 3 senaryo tanımlandı (normal reset, sınırda reset, reset'in olmaması gereken durum). Üçü de functional coverage'da bir bin'e sahip, üçü de dolmuş, ve ilgili assertion hiç ihlal edilmemiş. İşte rapor, işte test ID'leri."
Functional coverage, işte bu cümleyi kurabilmenizi sağlar.
Karşılaştırma: Ticari proje vs DO-254 projesi
| Konu | Ticari (örn. tüketici elektroniği) | DO-254 DAL A/B |
|---|---|---|
| Code coverage hedefi | Genellikle %90–95, "yeterince iyi" | %100 veya her boşluk için yazılı gerekçe |
| Boşlukların durumu | Çoğu zaman göz ardı edilir | Her biri analiz edilir, belgelenir, denetlenir |
| Ölü kod | Hoş görülür | Kaldırılır ya da güvenlik analiziyle gerekçelendirilir |
| Test kaynağı | Rastgele + yönlendirilmiş karışık | Gereksinim bazlı olmak zorunda; rastgele test ancak destekleyicidir |
| Functional coverage | Doğrulama planına bağlı | Gereksinim ID'lerine bağlı, izlenebilirlik matrisi zorunlu |
| Coverage raporu | İç ekip aracı | Sertifikasyon kanıt paketinin parçası |
| Gözden geçirme | İsteğe bağlı | Bağımsız gözden geçirme (DAL A'da bağımsızlık zorunlu) |
| Araç | Serbest | Aracın kendisinin kalifiye edilmesi gerekebilir (tool qualification) |
Son satıra dikkat edin: DO-254'te "coverage raporunu hangi araç üretti ve o araca neden güveniyoruz?" sorusu da sorulur. Bu, ticari projelerde hiç karşılaşmayacağınız bir sorudur.
Yeni başlayan bir mühendis için DO-254'te coverage pratiği
Bir DO-254 projesine girdiğinizde coverage ile ilgili karşılaşacağınız gerçekler:
- Hiçbir boşluk "önemsiz" değildir. "Bu branch zaten hiç çalışmaz" demeniz yetmez; neden çalışmadığını yazılı olarak göstermeniz gerekir.
- Coverage'ı kapatmak için test yazarken gereksinimden başlarsınız. "Şu satırı çalıştırmak için test yazayım" yaklaşımı yanlıştır. Doğrusu: "Bu satırı hangi gereksinim açıklıyor? O gereksinimin testi neden buraya ulaşmıyor?"
- Coverage raporu bir belge olarak saklanır. Simülasyon çalıştırıp ekranda görmek yetmez; rapor versiyonlanır, imzalanır, denetime sunulur.
- Covergroup değişikliği bir spesifikasyon değişikliği kadar ciddidir. Çünkü neyin doğrulandığının tanımını değiştiriyorsunuzdur; gözden geçirmeden geçmesi gerekir.
- Coverage, ekip işidir. Tasarımcı "bu kod neden var?" sorusuna, doğrulamacı "bu senaryo neden denenmedi?" sorusuna, sistem mühendisi "bu gereksinim gerçekten var mı?" sorusuna birlikte cevap verir.
Pratikte Coverage Closure Döngüsü
Hangi projede olursanız olun, coverage'ı hedefe taşıma süreci aynı döngüdür:
┌──────────────────────────────────────────────────────┐
│ 1. Regresyon koş, coverage veritabanlarını birleştir │
│ 2. Raporu incele: boşluklar nerede? │
│ 3. Her boşluğu sınıflandır: │
│ a) Eksik test → test yaz / constraint ayarla │
│ b) Eksik gereksinim→ spesifikasyonu güncelle │
│ c) Ölü/erişilemez → kodu kaldır veya gerekçele │
│ 4. Değişiklikleri gözden geçir │
│ 5. Başa dön — hedefe ulaşana kadar │
└──────────────────────────────────────────────────────┘
Bir ipucu: Coverage hole'larının çoğu, bug'dan çok "anlaşılmamış tasarım" işaretidir. Yeni başlayanlar bir boşluğu kapatmak için hemen test yazmaya koşar. Deneyimli mühendis önce "bu kod neden var ve neden çalışmıyor?" diye sorar. Bu soru, bazen bir test yazmaktan çok daha değerli bir bulguya götürür.
Uygulama: Coverage Simülatörü
Aşağıdaki araç, gerçek bir simülatörün coverage pencerelerini taklit eder. Küçük bir ALU kontrolcüsü (alu_ctrl.sv) üzerinde testleri tek tek ya da regresyon olarak koşun; kaynak penceresinde her satırın sayacının arttığını, kırmızı kalan statement'ları, branch'leri, condition'ları, toggle'ları, FSM'yi ve covergroup'u izleyin. Görev listesini tamamladığınızda bu dersin bütün kavramlarını elinizle denemiş olacaksınız.
Her satırın bir sayacı var.
Coverage açık derlediğinde simülatör tasarımın her satırına, her branch'ine, her bitine görünmez bir sayaç ekler. Simülasyon koştukça sayaçlar artar; sonunda 0'da kalanlar "missing" olarak raporlanır.
vlog +cover=sbcftStatement, branch, condition, FSM ve toggle için sayaçlar eklenir (instrumentation).vsim -coverageÇalışan her satırın sayacı +1. Hiç çalışmayan satır 0'da kalır.
test.ucdbTest bitince sayaçlar bir coverage veritabanına yazılır.vcover mergeTüm testlerin veritabanları toplanır: bir testin kaçırdığını diğeri kapatır.vcover reportKırmızı = missing. Her biri: eksik test mi, eksik gereksinim mi, ölü kod mu?Kendi regresyonunu koş, coverage'ı kapat.
Bir test seç ve çalıştır. Kaynak penceresinde satırların sayaçlarının arttığını, dalga formunu ve transcript'i canlı izle. Hedef: aşağıdaki görevleri tamamlayıp coverage'ı DO-254 seviyesinde kapatmak.
Bu rapor sana ne söylüyor?
Aklında kalsın.
Sık Yapılan Hatalar
- "Code coverage %100, demek ki tasarım doğru." Hayır. Code coverage doğruluk ölçmez;
a - börneğini hatırlayın. - "Functional coverage %100, demek ki her şeyi test ettim." Hayır. Yalnızca yazdığınız bin'leri doldurdunuz. Yazmadığınız senaryo ölçülmedi.
- "Coverage kapatmak için
bins'i genişleteyim." Bin'leri gevşeterek %100'e ulaşmak, kendinizi kandırmaktır. Hedef rakam değil, kanıttır. - "Boşluğu
excludeedeyim, geçsin." Her exclusion (waiver) bir gerekçe ister. DO-254'te gerekçesiz exclusion denetimde reddedilir. - "Toggle coverage çok gürültülü, kapatayım." Gürültülüdür ama bağlı olmayan portları ve kullanılmayan bitleri tam da o bulur.
- "Coverage doğrulamacının işi, tasarımcıyı ilgilendirmez." Coverage hole'larının üçte biri genellikle tasarım veya spesifikasyon sorusudur; tasarımcı masada olmalıdır.
Kendinizi Sınayın
Aşağıdaki durumlar için code coverage mı, functional coverage mı (ya da ikisi birden mi) sizi uyarır, düşünün:
- Bir
caseifadesinindefaultbranch'i hiç çalışmadı. - ALU'da çarpma işlemi hem pozitif hem negatif operandlarla test edildi ama "iki negatifin çarpımı" hiç denenmedi.
- Tasarımcı, spesifikasyonda olmayan bir "debug modu" eklemiş; testler bunu hiç açmıyor.
- Spesifikasyon "paket uzunluğu 64 bayt üzerinde ise hata ver" diyor; testlerde en uzun paket 60 bayt.
if (en && !busy)koşulundabusysinyali tüm testlerde 0 kaldı.
Cevaplar: 1 → code (branch). 2 → functional (cross). 3 → code (statement/branch boşluğu; DO-254'te "eksik gereksinim" bulgusu). 4 → functional (bin boş kalır); kod tarafında da o if branch'i alınmaz, yani ikisi birden. 5 → code (condition/toggle); busy'nin etkisi hiç görülmedi.
Önemli Noktalar
- Code coverage "kodun ne kadarı çalıştı?" sorusunu, functional coverage "spesifikasyonun ne kadarı denendi?" sorusunu cevaplar. Birbirinin yerine geçmezler; ikisi de gerekir.
- Code coverage otomatiktir ve ucuzdur; ölü kodu, eksik
else'leri, unutulmuş branch'leri bulur. Ama doğruluk ölçmez ve eksik özelliği göremez. - Functional coverage elle tanımlanır; senaryo kombinasyonlarını ve spesifikasyon boşluklarını bulur. Ama yalnızca yazdığınız kadar iyidir; gözden geçirilmelidir.
- "Code yüksek / functional düşük" → testler hedefsiz; "code düşük / functional yüksek" → kodda planda olmayan bir şey var. İkisi de eylem gerektirir.
- DO-254 projelerinde coverage bir rahatlık değil, sertifikasyon kanıtıdır. DAL A/B için Ek B'deki elemental analysis pratikte code coverage ile yapılır; her boşluk belgelenir, gerekçelendirilir ve denetlenir.
- DO-254'te testler gereksinim bazlıdır; functional coverage gereksinim ID'lerine bağlanır ve izlenebilirlik matrisinin parçası olur.
- Condition coverage, güvenlik-kritik mantıkta branch coverage'ın göremediği "etkisiz condition" hatalarını yakalar; DAL A/B'de özellikle beklenir.
- Coverage closure bir döngüdür: koş → incele → sınıflandır (eksik test / eksik gereksinim / ölü kod) → gözden geçir → tekrar. Boşluğu kapatmak için test yazmadan önce "bu kod neden var?" diye sorun.