Kod Kapsamının Açıklaması: Hat ve Şube Kapsamı ve %100’ün Gerçek Anlamı

  1. Ana sayfa
  2. Blog
  3. Yazılım Testi

Yazılım Testi

Kod Kapsamının Açıklaması: Hat Kapsamı ve Şube Kapsamı ve %100’ün Gerçek Anlamı

Kapsam size testlerinizin hangi kodu çalıştırdığını söyler. Testlerin herhangi bir şeyi kontrol edip etmediğini size söylemez. Farkı göstermek için küçük bir modülü üç şekilde ölçtük.

8 dk okuma
Kod kapsamı açıklandı: hat ve şube kapsamı ve %100'ün gerçekte ne anlama geldiği

Önemli noktalar

  • Kod kapsamı testler sırasında kodunuzun ne kadarının çalıştığını ölçer.
  • Şube kapsamı hat kapsamından daha katıdır ve daha kullanışlıdır.
  • Testimizde, hiçbir iddianın bulunmadığı bir paket hâlâ %100 kapsama ulaştı.
  • Kalitenin kanıtı olarak değil, test edilmemiş kodu bulmak için kapsamı kullanın.

Bir ekip gururla %95 kod kapsamını rapor ediyor, ardından “kapsanan” bir satıra bir hata gönderiyor. Bu bir çelişki değil. Kapsam dar bir soruyu yanıtlıyor: testler bu kodu yürüttü mü? Sonucu kontrol edip etmedikleri tamamen farklı bir sorudur.

Python’u cover.py 7.17 ve pytest 9.2 ile kullandık. Aşağıdaki her sayı ve rapor kendi çalışmamıza aittir. Fikirler her dilde geçerlidir.

Kod kapsamı nedir?

Kod kapsamı, otomatik testleriniz çalışırken kodunuzun çalışan yüzdesidir. Bir araç, hangi satırların ve isteğe bağlı olarak hangi dalların yürütüldüğünü kaydeder ve ardından neyin kaçırıldığını bildirir.

En çok tersi durumda kullanışlıdır. Bir alandaki kapsama alanının düşük olması, size kesinlikle testlerin bu alanı uygulamadığını gösterir. Yüksek kapsama alanı size çok daha az şey anlatır.

Kapsam türleri

Tür Soru cevap verir
İşlev Her işlev en az bir kez çağrıldı mı?
Satır (bildirim) Her hat en az bir kez çalıştı mı?
Şube Her biri if her iki yöne mi gitti; doğru ve yanlış?
Durum Birleşik koşulun (a and b) her bir parçası her iki değeri de aldı mı?
MC/DC Her koşul bağımsız olarak sonucu değiştirdi mi? Güvenlik açısından kritik yazılımlarda kullanılır.

Her seviye bir üst seviyeden daha katıdır. Çoğu ekip hat ve şube kapsamını takip eder. Durum kapsamı ve MC/DC, takım desteğinin uzmanlaştığı havacılık ve otomotiv standartlarında görülür.

Ölçtüğümüz kod

def shipping_fee(total, is_member, express=False):
    if total < 0:
        raise ValueError("total cannot be negative")
    fee = 0 if total >= 1000 else 50
    if is_member:
        fee = max(fee - 25, 0)
    if express:
        fee += 100
    return fee

İlk test dosyamızda iki test vardı:

def test_regular_order():
    assert shipping_fee(500, False) == 50

def test_member_express():
    assert shipping_fee(500, True, express=True) == 125

Şube ölçümü açıkken çalıştırdık:

coverage run --branch -m pytest test_shipping.py
coverage report -m

Raporun okunması

Name          Stmts   Miss Branch BrPart  Cover   Missing
---------------------------------------------------------
shipping.py       9      1      6      1    87%   3
  • Strmts 9, Miss 1: dokuz yürütülebilir ifade, biri hiç çalıştırılmadı.
  • Şube 6, BrBölüm 1: üç if karar, altı olası sonuç verir. Bir karar yalnızca tek bir yöne gitti.
  • Eksik 3: 3. satır, raise ValueError, hiç çalışmadı. Hiçbir test negatif toplamı geçemedi.

Düzeltme, hata yolu için bir testtir. Ayrıca büyük bir sipariş için bir test de ekledik:

def test_free_over_1000():
    assert shipping_fee(1000, False) == 0

def test_negative_total():
    with pytest.raises(ValueError):
        shipping_fee(-1, False)

Her iki dosyada da raporda %100 görüldü ve eksik satır veya kısmi dallanma yoktu. Hata yolları, klasik boşluk kapsamı bulgularıdır; bu nedenle, eşdeğerlik bölümleme gibi tekniklerle tasarlanan geçersiz giriş testleri onunla çok iyi eşleşir.

Raporun sakladığı şey

İlk rapora tekrar bakın. Sadece 3. satırın eksik olduğu söylendi. Ancak ilk iki testin her ikisi de toplam 500 adet kullandı; dolayısıyla 1000 veya üzeri siparişler için ücretsiz gönderim kuralı hiçbir zaman test edilmedi ve raporda bu kural işaretlenmedi.

Bunun nedeni fee = 0 if total >= 1000 else 50‘in tek satırda olmasıdır. cover.py satırlar arasındaki dalları ölçer, dolayısıyla tek bir satır içindeki koşullu ifade, yürütülen tek bir ifade olarak sayılır. Bu kuralda >= yerine > gibi bir hata olsaydı, ilk paket hala hiçbir ipucu olmadan %87 gösteriyordu. Onu yakalayan şey, sınır değeri analizinde açıklandığı gibi, bizzat sınırın testleridir.

Hiçbir kontrol olmadan %100 kapsam

Daha sonra, her yolu çağıran ancak hiçbir şey öne sürmeyen, kasıtlı olarak zayıf bir test yazdık:

def test_runs_everything_but_checks_nothing():
    shipping_fee(500, True, express=True)
    shipping_fee(1000, False)
    shipping_fee(500, False)
    try:
        shipping_fee(-1, False)
    except ValueError:
        pass
shipping.py       9      0      6      0   100%

%100 hat ve şube kapsamına ulaştı. İşlev herhangi bir sayıyı döndürebilir ve bu test yine de başarılı olacaktır. Bu, kapsamın temel sınırıdır: doğrulamayı değil, yürütmeyi ölçer.

İpucu: Bir çekme isteğini incelerken yalnızca kapsam değişikliğini değil, iddiaları da okuyun. Anlamlı bir iddia olmadan kapsamı ekleyen bir test yalnızca yanlış güveni artırır.

Testlerin gerçekten hataları yakalayıp yakalamadığını ölçmek için mutasyon testini kullanın. Python için mutmut, Java için PIT veya JavaScript için Stryker gibi bir araç, kodunuzda >=‘yi >‘e çevirmek gibi küçük değişiklikler yapar ve bir testin başarısız olup olmadığını kontrol eder. İddiasız testimiz her mutasyonun hayatta kalmasına izin verecektir.

Hangi hedefi belirlemeli

Evrensel olarak doğru bir sayı yoktur. Pratik rehberlik:

  • %100’ün peşinden koşmayın. Son yüzde birkaçı genellikle önemsiz kodları test etmek veya yalnızca çizgilere değinen testler yazmak anlamına gelir.
  • Birçok ekip genel olarak kabaca %70 ila 85’i hedefliyor ve temel iş mantığına ilişkin beklentiler daha yüksek.
  • Rakamı değil, trendi izleyin. Her yayında düşen kapsama alanı bir uyarı işaretidir.
  • Eski kodun tamamını bir kerede zorlamak yerine, çekme isteklerinde yeni kodun kapsanmasını zorunlu kılın.
  • Oluşturulan kod gibi önemli olmayan şeyleri açık kurallarla hariç tutun.

Goodhart yasası geçerlidir: Bir önlem hedef haline geldiğinde iyi bir önlem olmaktan çıkar. Zor hedefler, iddiasız örneğimiz gibi testleri teşvik eder.

Dile göre araçlar

Dil Ortak araçlar
Python kapsama.py, pytest-cov
JavaScript / TypeScript Jest ve Vitest’te yerleşik olarak İstanbul (nyc)
Java JaCoCo
.NET Yatak Örtüsü
Git teste git - kapak
Raporlama Codecov, SonarQube, Tulumlar

CI’da kapsam

Kapsamı CI ardışık düzeninizin bir parçası olarak çalıştırın ve incelemecilerin hangi yeni satırların test edilmediğini görebilmesi için raporu yayınlayın. Coverage.py ile coverage report --fail-under=80 bir eşiğin altındaki derlemede başarısız oluyor. Herhangi bir eşiği makul düzeyde tutun ve bunu yeni koda ilişkin bir kuralla birleştirin; böylece tek bir büyük eski dosya her değişikliği engellemez.

Kapsamın ötesinde: sorulacak daha iyi sorular

  • Testler kodun riskli ve sık değiştirilen kısımlarını kapsıyor mu?
  • Sadece mutlu yol değil, sınırlar ve hata yolları da test ediliyor mu?
  • Bu satır yanlış olsaydı test başarısız olur muydu?
  • Testler her değişiklikte yürütülecek kadar hızlı ve kararlı mı?

Bunlar herhangi bir test stratejisine aittir. Kapsam yalnızca ilkinin yanıtlanmasına yardımcı olur.

Kodu hariç tutma ve HTML raporlarını okuma

Hata ayıklama yardımcıları veya yalnızca bir komut dosyası elle başlatıldığında çalışan bir blok gibi bazı kodlar doğrudan test etmeye değmez. kapsama.py, yorum içeren satırları hariç tutmanıza olanak tanır:

if __name__ == "__main__":  # pragma: no cover
    main()

Ayrıca yapılandırmada ölçülecek hariç tutmaları ve kaynak klasörleri de ayarlayabilirsiniz, örneğin pyproject.toml‘de:

[tool.coverage.run]
branch = true
source = ["shop"]

[tool.coverage.report]
show_missing = true
exclude_also = ["if TYPE_CHECKING:"]

Hariç tutmaları dikkatli kullanın ve bunları kod gibi gözden geçirin. Her biri bazı hatların asla kontrol edilmeyeceği kararıdır. Sadece sayıyı yükseltmek için test edilmesi zor bir hata işleyicisini hariç tutmak amacı boşa çıkarır.

Günlük işler için HTML raporu terminal tablosundan daha kullanışlıdır. coverage html‘i çalıştırın ve htmlcov/index.html‘yi açın. Her dosya yürütülen satırlar yeşil, kaçırılan satırlar kırmızı ve kısmi dallanmalar sarı renkte gösterilir, böylece hangi if‘ün asla başka bir yol izlemediğini bir bakışta görebilirsiniz. Pek çok editör kenar boşluğunun kapsamını da gösterebilir; bu da boşlukları daha sonra değil, siz kodu yazarken görünür hale getirir.

Yeniden düzenleme öncesi kapsam

Kapsam aynı zamanda yeniden düzenleme öncesinde bir güvenlik kontrolüdür. Bir modülü yeniden yapılandırmayı planlıyorsanız önce raporuna bakın. Kırmızı alanlarda davranış değiştiğinde sizi uyaracak testler yoktur; bu nedenle başlamadan önce mevcut davranışı yakalayan karakterizasyon testleri ekleyin. Bu şekilde kullanıldığında kapsama alanı hedef olmaktan çıkar ve pratik bir planlama aracı haline gelir.

Aynı rapor, bir hata üretime kaçtığında da yardımcı olur. Hatanın yaşadığı satırı bulun ve herhangi bir testin çalıştırılıp çalıştırılmadığını kontrol edin. Değilse, kapatmaya değer bir boşluk buldunuz. Eğer bir test bunu çalıştırdıysa, sorun zayıf bir iddiadır; iddiasızlık örneğimizin gösterdiği durum da tam olarak budur. Her iki cevap da size paketi nasıl geliştireceğinizi anlatıyor.

Son sözler

Kod kapsamı bir el feneridir, bir derece değil. Özellikle hata işleme olmak üzere hiçbir testin dokunmadığı kodu bulmak için dal kapsamını kullanın ve ardından gerçek iddialarda bulunan testler yazın. Çalışmamızdan bir sonucu hatırlıyorsanız, şunu yapın: Hiçbir şeyi kontrol etmeyen bir testle %100 kapsama ulaşıldı.

Sık sorulan sorular

Testte kod kapsamı nedir?

Otomatik testler yürütülürken satırlar, dallar veya koşullarla ölçülen, yürütülen kodun yüzdesidir. Testlerin doğrulayıp doğrulamadığını değil, hangi testlerin dokunduğunu gösterir.

Hat ve şube kapsama alanı arasındaki fark nedir?

Hat kapsama alanı her hattın çalışıp çalışmadığını kontrol eder. Şube kapsamı her kararın her iki yönde de gittiğini kontrol eder. Şube kapsamı, hat kapsamının kaçırdığı denenmemiş yolları bulur.

%100 kod kapsamı iyi mi?

Tek başına değil. Testimizde hiçbir iddiası olmayan bir paket %100’e ulaştı. Mükemmel bir sayı yerine önemli kod üzerinde anlamlı testler yapmayı hedefleyin.

İyi bir kod kapsama yüzdesi nedir?

Pek çok ekip genel olarak kabaca %70 ila 85’i hedefler ve daha fazlası kritik mantık üzerinedir. İddiaların eğilimi ve kalitesi, kesin sayıdan daha önemli.

Mutasyon testinin kapsamdan farkı nedir?

Mutasyon testi kodunuzu biraz değiştirir ve testin başarısız olup olmadığını kontrol eder. Testlerin kapsamın tespit edemediği hataları tespit edip etmediğini ölçer.

Öğrenmeye devam et

Stack Quora ile çalışın

Test, WordPress veya SEO konusunda yardıma mı ihtiyacınız var?

Ekiplerin daha iyi yazılımlar sunmasına ve sitelerini büyütmesine yardımcı oluyoruz. Bize ne üzerinde çalıştığınızı söyleyin, biz de bir sonraki adım için net bir öneride bulunalım.

Okumaya devam et

Daha fazla kılavuz test, yapay zeka ve modern geliştirme

Bu makaleyi beğendiniz mi? Bir konu seçin ve doğrudan en yeni eğitimlerimize geçin.

Yapay zekâ

Yapay Zeka Halüsinasyonları Açıklandı: Dil Modelleri Neden İşleri Düzeltiyor ve Nasıl Azaltılabilir?

Yapay zeka halüsinasyonları açıkladı: ne olduklarını, dil modellerinin bunları neden ürettiğini, yaygın türlerini, temellendirme ve yönlendirmelerle…

Makaleyi okuyun →
DevOps

Açıklanan Ortam Değişkenleri: .env Dosyaları, Sırlar ve Yapılandırma Doğru Yapıldı

Çalıştırdığımız Python örnekleriyle açıklanan ortam değişkenleri: bunları okumak ve ayarlamak, neden her değerin bir dize olduğu, .env dosyaları, sü…

Makaleyi okuyun →
Yazılım geliştirme

API Hız Sınırlamasının Açıklaması: Algoritmalar, Başlıklar ve 429 Hatalarının Ele Alınması

API hızı sınırlaması, çalıştırdığımız bir simülasyonla açıklanmıştır: belirteç kümesi, sabit pencere, kayan pencere, 429 yanıt, hız sınırı başlıklar…

Makaleyi okuyun →
Test otomasyonu

Python'da alay etme: Unittest.mock, patch ve Testleri Yalan Yapan Hatalar

Unittest.mock ile Python'da alay etme, test edildi: Sahte ve dönüş_değeri, yan_etki, bir adın kullanıldığı yerde yama uygulama, spesifikasyon ve oto…

Makaleyi okuyun →
Yazılım testi

Kod Kapsamının Açıklaması: Hat ve Şube Kapsamı ve %100'ün Gerçek Anlamı

Kod kapsamı gerçek bir kapsama.py çalışmasıyla açıklanmıştır: hat, şube ve durum kapsamı, bir raporun okunması, %100 kapsamın neden hâlâ hataları ka…

Makaleyi okuyun →
Veritabanları ve SQL

SQL'de DELETE vs TRUNCATE vs DROP: Farklılıklar, Geri Alma ve Her Biri Ne Zaman Kullanılmalı

DELETE vs TRUNCATE vs DROP test edilmiş SQL ile açıklandı: her birinin neyi kaldırdığı, geri aldığı, tetiklediği, kimlik sıfırlaması, hızı ve Postgr…

Makaleyi okuyun →
Veritabanları ve SQL

Açıklanan SQL Görünümleri: Örneklerle Tuzakları Oluşturun, Kullanın ve Önleyin

Çalıştırdığımız sorgularla açıklanan SQL görünümleri: görünüm oluşturma, canlı sonuçlar, sütunları gizleme, performans, güncellenebilir ve gerçekleş…

Makaleyi okuyun →
Yazılım geliştirme

TypeScript Arayüzü ve Tür: Gerçek Farklılıklar, Derleyiciyle Test Edildi

TypeScript arayüzü ve türü, gerçek derleyiciyle kontrol edildi: her ikisinin de yapabileceği, yalnızca birinin yapabileceği, bildirim birleştirme, g…

Makaleyi okuyun →
Yazılım geliştirme

Python *args ve **kwargs'ın Açıklaması: Açık Örneklerle Esnek Fonksiyonlar

Python *args ve **kwargs çalıştırdığımız kodla açıklanmıştır: paketleme ve paketten çıkarma, parametre sırası, yalnızca anahtar kelime ve yalnızca k…

Makaleyi okuyun →
Yazılım geliştirme

Python Lambda İşlevleri: Söz Dizimi, Gerçek Kullanımlar ve Ne Zaman Kullanılmaması Gerektiği

Çalıştırdığımız kodla açıklanan Python lambda işlevleri: sözdizimi, anahtarla sıralama, harita ve filtre, kapatmalar, geç bağlama tuzağı ve normal b…

Makaleyi okuyun →
Yapay zekâ

Yapay Zeka Ajanları Nelerdir? Çalıştırabileceğiniz Basit Bir Aracı Döngüsüyle Nasıl Çalışırlar?

Yapay zeka ajanları nedir? Aracı döngüsüne, araçlara, belleğe ve korkuluklara ilişkin basit bir kılavuz, çalıştırdığımız küçük bir Python döngüsü, g…

Makaleyi okuyun →
DevOps

İzleme ve Gözlemlenebilirlik: Günlükler, Metrikler ve İzlerle Gerçek Fark

İzleme ve gözlemlenebilirliğin açıklanması: bilinen ve bilinmeyen arızalar, günlükler, ölçümler ve izler, ödeme olayının gözden geçirilmesi, altın s…

Makaleyi okuyun →
DevOps

Docker Birimleri ve Bağlama Bağlantıları: Konteyner Verilerini Doğru Şekilde Kalıcılaştırın

Docker birimleri ile bağlama bağlamaları arasındaki karşılaştırma açıklandı: kapsayıcı verilerinin neden kaybolduğu, adlandırılmış birimler, bağlama…

Makaleyi okuyun →
Test otomasyonu

TDD ve BDD: Temel Farklılıklar, Her İki Şekilde Geliştirilmiş Bir Özellik ve Her Birinin Ne Zaman Kullanılacağı

TDD ve BDD, her iki yönde de oluşturulmuş bir indirim özelliğiyle açıklandı: çalıştırdığımız kodla kırmızı-yeşil-refactor, Verilen-Ne Zaman-O Zaman …

Makaleyi okuyun →
Yazılım geliştirme

Git merge vs rebase: farklar, örnekler ve hangisi ne zaman kullanılır

Git merge vs rebase; gerçek log çıktısı, karşılaştırma tablosu, rebase'in altın kuralı ve güvenli bir ekip iş akışıyla anlatılıyor.

Makaleyi okuyun →
Yazılım geliştirme

Python Liste Üreteci (List Comprehension): Sözdizimi, Örnekler ve Kaçınılacak Durumlar

Python list comprehension anlatımı: sözdizimi, filtreleme, if-else, iç içe döngüler, ölçülmüş süreler ve düz for döngüsünün daha iyi olduğu durumlar.

Makaleyi okuyun →
Veritabanları ve SQL

SQL JOIN Örneklerle Açıklama (Inner, Left, Right, Full)

SQL JOIN'leri örnek tablolar ve sorgularla adım adım öğrenin: INNER, LEFT, RIGHT, FULL, CROSS ve SELF; yaygın hatalar ve performans ipuçları.

Makaleyi okuyun →