İçeriğe geç
academia.sh

Ders 04 / 15

Testlerin İncelenmesi

Üç test kusurunun üçü de okunmuş öbeklerde duruyor ve o öbeklerde başka eksenlerden bulgu veren inceleyenler var; okunmamış öbekte kaçan kusur sayısı beş eksenin beşinde de 0 ve test ekseni kapatılınca bulunan 22'den 19'a iniyor.

İçindekiler

Önceki ders bir kusurun kaçmasının bu kurguda tek bir nedeni olduğunu varsaymıştı: o eksene kimsenin bakmaması. Ama kaçmanın ikinci bir nedeni daha olabilir — kusurun bulunduğu metnin hiç okunmamış olması. İki neden aynı sonucu verir ve tabloda aynı sütunda görünür; oysa ikisine verilecek karşılık aynı değildir.

Bu ders o ayrımı ölçer ve ölçümü test ekseninde yapar. Test ekseninin seçilmesi rastgele değil: testler değişikliğin gövdesiyle aynı dosyalarda ya da onlara komşu dosyalarda durur, yani başka eksenlere bakan inceleyenlerin gözünün önünden geçer. Sorusu şudur: bir kusur, okunmuş bir metnin içinde, o metni okuyan birden çok kişinin gözü önünde kaçabilir mi.

Testin Kendisi de İncelenir

Test seviyeleri, test piramidi, kapsam ölçütleri ve test yazma teknikleri Yazılım Kalitesi ve Test müfredatında kuruldu ve burada tekrarlanmıyor. Bu dersin konusu testin nasıl yazılacağı değil, incelemede testin kendisine bakıldığında ne bulunduğudur.

Ayrım şurada durur. Bir değişikliğin testleri iki ayrı rolde bulunur. Birinci rolde test bir delildir: gövdenin doğru olduğunu gösterir ve gerçekleştirim eksenine bakan okuma ona dayanır. İkinci rolde test bir inceleme nesnesidir: kendisi de yazılmış koddur ve kendi kusurlarını taşır.

İkinci rol atlandığında ilk rol çöker. Gövdenin doğruluğuna testlerin geçmesine bakarak karar veren bir okuma, testlerin ne doğruladığını denetlemediyse hiçbir şeye bakmamış olur. Test ekseni tam olarak bu denetimdir.

Testin Taşıdığı Üç Kusur

Kapsam. Değişikliğin getirdiği yeni yol test edilmemiştir. Testler vardır, geçerler ve sayıları da artmış olabilir; ama değişen davranışın kendisine dokunan bir test yoktur. Bu kusurun incelemede görünen izi, değişen gövdenin bir dalına karşılık gelen bir iddianın bulunmamasıdır.

Anlamlılık. Test yeni yolu çalıştırır ama bir şey doğrulamaz. Yalnız çağrının hata fırlatmadığını sınayan bir test, gövde ne dönerse dönsün geçer. Aynı sınıfa, sonucu kendi hesaplayan testler de girer: beklenen değeri gövdenin kullandığı ifadeyle üreten bir iddia, gövde yanlış olsa da doğrulanır.

Kırılganlık. Test, davranışa değil gerçekleştirimin iç ayrıntısına bağlanmıştır: çağrı sırasına, iç bir yapının alan adına, kayıt satırının tam metnine. Böyle bir test davranış değişmeden kırılır ve kırıldığında düzeltilmesi gereken şey gövde değil testtir.

Üçünün incelemedeki görünürlüğü aynı değildir. Kapsam kusuru sayılabilir bir eksikliktir ve gövdenin dalları ile testlerin durumları yan yana konduğunda ortaya çıkar. Anlamlılık kusuru testin metnini okumayı gerektirir ve test sayısına bakan bir okumadan kaçar, çünkü hiçbir şey doğrulamayan bir test de bir testtir ve sayıya girer. Kırılganlık kusuru üçünün en zorudur: test bugün geçer ve kusurun bedeli sonraki bir değişiklikte, kendisiyle ilgisi olmayan bir işi durdurarak ödenir.

# ogretilen inceleme notu ornegi , calistirilmamistir

kapsam        Degisiklik iki yeni dal getiriyor; testler yalnizca ilk dali
              cagiriyor. Ikinci dal icin bir durum eklenmesi gerekiyor.

anlamlilik    Testin tek iddiasi cagrinin hata firlatmadigi. Gövde herhangi
              bir deger dondurse de bu test geciyor; donen degerin
              dogrulanmasi gerekiyor.

kirilganlik   Test, kayit satirinin tam metnini karsilastiriyor. Kayit
              bicimi degistiginde davranis ayni kalsa da test kirilacak;
              karsilastirma sonuca baglanabilir.

Üç not da testin bir yerini gösteriyor ve neyin eklenmesiyle kapanacağını söylüyor. Bu blok bir örnektir ve çalıştırılmaz; dersin sayıları yalnız ölçüm bloğundan gelir.

Test Değişiklikle Aynı Elden Çıkar

Test ekseninin ayrı bir okuma gerektirmesinin yapısal bir nedeni var ve bu neden önceki dersin sorusuna bağlanıyor: gerçekleştirim eksenine bakan okuma, gövdenin ne yapması gerektiğini bir yerden çıkarmak zorundaydı ve kullanılabilecek kaynaklardan biri testlerdi.

Sorun şu ki testler aynı değişikliğin parçasıdır. Gövde ile test aynı anda, aynı anlayışla yazılır. Gövdenin dayandığı bir yanlış anlama varsa, test de aynı yanlış anlamayı kaydeder ve gövdeyi doğrular. Bu durumda testin geçmesi bir delil değil, bir yankıdır.

Bunun incelemedeki sonucu doğrudandır: testin doğruluğu, gövdenin doğruluğundan bağımsız olarak sınanmalıdır. Test ekseni bunu yapan tek okumadır ve bakacağı şey testin geçip geçmediği değil, testin ne iddia ettiğidir. Bir iddianın gövdeyle aynı ifadeyi tekrarlaması, gövdenin dallarından birini hiç çağırmaması ya da hiçbir sonucu karşılaştırmaması, testin çalıştırılmasıyla değil okunmasıyla görülür.

Ölçüm bu bağımlılığı modellemez — test sınıfındaki kusurlar, gerçekleştirim sınıfındakilerden bağımsız kusurlardır. Modelin yalınlığı burada ölçümün lehinedir: bağımlılık eklenseydi test ekseninin kapatılmasının bedeli tabloda görünenden büyük çıkardı.

Okunmuş Metnin İçinde Kaçmak

Kurguda bir kusurun bulunması iki koşula bağlıdır: kusurun sınıfı inceleyenin ekseninde olacak, ve kusurun bulunduğu öbek inceleyenin okuduğu öbekler arasında olacak. İki koşuldan biri sağlanmazsa kusur kaçar.

Bu konunun ölçeğinde ikinci koşul her zaman sağlanır: değişiklik 12 öbek, dikkat de 12 öbek. Dolayısıyla bu derste hiçbir kusur okunmadığı için kaçmaz. Ölçüm bunu varsaymak yerine sayar ve kaçanları ikiye ayırır — okunmuş öbekte kaçanlar ve okunmamış öbekte kaçanlar.

İkinci sütunun sıfır çıkması, birinci sütunun tamamının eksen kaçışı olduğunu gösterir. Bu, dersin sorusuna doğrudan yanıttır: kaçan kusur, kimsenin bakmadığı bir yerde değil, herkesin okuduğu bir yerde duruyordur.

Ölçümün Varsayımları

  • IE23 — Ortak kurgu değişmez: 600 satır, 12 öbek, 24 kusur, dikkat 12 öbek.
  • IE24 — Bir öbek 50 satırdır ve okuma birimi öbektir; bir öbeği okuyan inceleyen, o öbeğin tamamını görmüş sayılır.
  • IE25 — “Aynı öbekteki öteki sınıf” sütunu, o öbekte bulunan ve test dışındaki eksen sınıflarından olan kusurların sınıf adlarıdır.
  • IE26 — “O öbekte bulgu veren başka eksen” sayısı, o öbekte kendi sınıfından bir kusur bulunan test dışı eksen sayısıdır. Bu eksene bakan bir inceleyen o öbekte bir not düşmüş demektir; öbeği okuduğu kurguca kesindir.
  • IE27 — Okunmuş öbekte kaçan kusur, öbeği okunan ama sınıfı inceleyenin ekseninde olmayan kusurdur. Okunmamış öbekte kaçan, öbeği hiç okunmayan kusurdur.
  • IE28 — İkinci bölümdeki her satır tek eksenli tek bir okumadır; kaçan sütunları o tek okumaya göredir.
  • IE29 — Testin geçmesi ya da kalması ölçümde yoktur; ölçülen şey testin incelemede bulunan kusurudur, çalıştırıldığında verdiği sonuç değil.
  • IE30 — Öbek düzeyinde çözünürlük 1/12 = 0,083, kusur düzeyinde 1/24 = 0,042.

Ölçüm

"""Testlerin incelenmesi: okunmus obekte kacan kusur.

Bolum 1 - test kusurlarinin durdugu obekler ve ayni obekteki oteki siniflar.
Bolum 2 - her tek eksenli okuma icin kacanin okunmus ve okunmamis ayrimi.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


TAM = set(EKSENLER)
d = degisiklik(600)
test_kusurlari = [k for k in d["kusurlar"] if k["sinif"] == "test"]

print(f"{'kusur':>5s} {'öbek':>4s} {'aynı öbekteki öteki sınıf':<28s} "
      f"{'o öbekte bulgu veren başka eksen':>32s}")
for k in test_kusurlari:
    komsu = sorted({o["sinif"] for o in d["kusurlar"]
                    if o["obek"] == k["obek"] and o["sinif"] in EKSENLER
                    and o["sinif"] != "test"})
    print(f"{k['no']:5d} {k['obek']:4d} {', '.join(komsu):<28s} "
          f"{len(komsu):32d}")
dolu = {k["obek"] for k in d["kusurlar"]}
cok = sum(1 for o in range(d["obek"])
          if len({k["sinif"] for k in d["kusurlar"] if k["obek"] == o}) > 1)
print(f"{d['obek']} öbeğin {len(dolu)}'inde en az bir kusur var; "
      f"{cok} öbekte birden çok sınıftan kusur var")

print()
print(f"{'eksen':<15s} {'okunan öbek':>11s} {'bulunan':>7s} "
      f"{'okunmuş öbekte kaçan':>20s} {'okunmamış öbekte kaçan':>22s}")
for e in EKSENLER:
    b = incele(d, {e})
    okunan = set(range(min(DIKKAT, d["obek"])))
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    ok = sum(1 for k in kacan if k["obek"] in okunan)
    yok = sum(1 for k in kacan if k["obek"] not in okunan)
    print(f"{e:<15s} {len(okunan):11d} {len(b):7d} {ok:20d} {yok:22d}")

print()
DORT = TAM - {"test"}
for ad, eksenler in (("beş eksen", TAM), ("testsiz dört eksen", DORT)):
    b = incele(d, eksenler)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    tk = sum(1 for k in kacan if k["sinif"] == "test")
    print(f"{ad:<20s} bulunan {len(b):2d}  kaçan {len(kacan):2d}  "
          f"test kaçan {tk}  yazılmayan kaçan "
          f"{sum(1 for k in kacan if k['sinif'] == YAZILMAYAN)}")
kusur öbek aynı öbekteki öteki sınıf    o öbekte bulgu veren başka eksen
    3    9 gerceklestirim                                              1
    7    1 arayuz, bicim                                               2
   19    7 arayuz                                                      1
12 öbeğin 11'inde en az bir kusur var; 7 öbekte birden çok sınıftan kusur var

eksen           okunan öbek bulunan okunmuş öbekte kaçan okunmamış öbekte kaçan
arayuz                   12       3                   21                      0
gerceklestirim           12       6                   18                      0
test                     12       3                   21                      0
belge                    12       3                   21                      0
bicim                    12       7                   17                      0

beş eksen            bulunan 22  kaçan  2  test kaçan 0  yazılmayan kaçan 2
testsiz dört eksen   bulunan 19  kaçan  5  test kaçan 3  yazılmayan kaçan 2

Aynı Öbek, Ayrı Eksen

Üst tablo üç test kusurunu tek tek gösteriyor ve üçü de yalnız başına durmuyor.

3 numaralı kusur dokuzuncu öbekte ve aynı öbekte bir gerçekleştirim kusuru var. 7 numaralı kusur birinci öbekte ve orada hem arayüz hem biçim kusuru var. 19 numaralı kusur yedinci öbekte ve yanında bir arayüz kusuru duruyor.

Sağdaki sütun bunun anlamını veriyor: 1, 2, 1. Bu sayılar, o öbekte kendi sınıfından bir kusur bulmuş eksenlerin sayısıdır. Yani birinci öbekte iki ayrı inceleyen not düşmüştür; ikisi de o elli satırı okumuştur; ve ikisi de aynı elli satırın içindeki test kusurunu görmemiştir. Aynı şey dokuzuncu ve yedinci öbek için birer kez geçerlidir.

Üç kusur üç ayrı öbekte duruyor; öbek düzeyinde bu 3/12, yani 0,250’dir. Test kusurlarının bulunduğu öbekler değişikliğin dörtte birine denk geliyor ve bu öbeklerin hiçbiri okunmamış değil. Öbek düzeyinde ölçülebilen en küçük fark 1/12 = 0,083 olduğuna göre bu pay ölçüm bandının rahatça içindedir.

Alt satır kurgunun yoğunluğunu veriyor: 12 öbeğin 11’inde en az bir kusur var ve 7 öbekte birden çok sınıftan kusur var. Değişiklik dar bir yere sıkışmış değil; sınıflar birbirine karışmış hâlde duruyor. Bir inceleyenin okuduğu her öbekte, kendi bulduğunun yanında bulmadığı bir şey olma olasılığı yüksek.

Kaçmanın Tek Nedeni

Orta tablo bu dersin ayrımını sayıya çeviriyor. Beş satırın hepsinde okunan öbek 12 ve okunmamış öbekte kaçan 0.

Sıfır sütunu şunu söylüyor: bu ölçekte hiçbir kusur, metni okunmadığı için kaçmıyor. Kaçan kusurların tamamı — arayüzde 21, gerçekleştirimde 18, testte 21, belgede 21, biçimde 17 — okunmuş öbeklerin içinde duruyor. Her birinin tek bir nedeni var: inceleyenin ekseninde o sınıf yok.

Bu, incelemenin en aldatıcı yanını adlandırıyor. Bir inceleyen değişikliğin tamamını okuduğunu söyleyebilir ve doğru söylüyordur; okuma gerçekten yapılmıştır. Ama “tamamını okudum” cümlesi “tamamına baktım” anlamına gelmez. Okuma bir kapsama, bakma bir eksene aittir ve tablo ikisinin ayrı olduğunu gösteriyor.

Bunun incelemenin kaydına dokunan bir karşılığı var. Bir inceleme “bir şey bulamadım” diyerek kapandığında geriye kalan bilgi eksiktir: hangi eksenlerde bakıldığı yazılı değildir. Aynı değişikliğe sonradan bakan biri, kapanmış incelemenin hangi sınıfları kapsadığını bilemez ve tabloya göre bu bilgi, bulunan kusur listesi kadar belirleyicidir.

Kaydın taşıması gereken şey bu yüzden yalnız bulgu listesi değil, bakılan eksen listesidir. “Arayüz ve gerçekleştirim eksenlerinde okundu, test ve belge eksenlerinde okunmadı” biçiminde bir not bulunan sayısını değiştirmez; kaçanların hangi sınıflarda olduğunu önceden söyler. Bu not değişiklik hakkındadır ve incelemenin kapsamını kaydeder, bakan kişinin başarısını değil.

Alt iki satır kaybın büyüklüğünü veriyor. Beş eksene bakan okuma 22 buluyor, test ekseni kapatıldığında 19. Kaçan 2’den 5’e çıkıyor ve fark tam olarak 3 test kusuru. Test ekseninin payı, önceki derste ölçülen kurala uygun biçimde sınıfının büyüklüğü kadar.

Bu üç kusurun kaçmasının pratikteki karşılığı, ötekilerden bir bakıma daha ağırdır. Kaçan bir test kusuru yalnız kendisi kalmaz; testin delil rolünü de bozar. Kapsamı eksik bir test takımı, gerçekleştirim ekseninde çalışan sonraki okumalara yanlış bir güvence verir — testler geçiyordur, ama geçtikleri şey değişen davranış değildir.

Özet

  • Test bir değişiklikte iki rol taşır: gövdenin doğruluğunun delili ve kendisi de incelenen bir nesne. İkinci rol atlandığında birincisi dayanaksız kalır.
  • Testin taşıdığı kusurlar üç türdür: kapsam (yeni yol test edilmemiş), anlamlılık (iddia bir şey doğrulamıyor), kırılganlık (test iç ayrıntıya bağlanmış).
  • Üç test kusuru 9, 1 ve 7 numaralı öbeklerde duruyor ve o öbeklerde sırasıyla 1, 2, 1 başka eksen bulgu vermiş; o öbekleri okuyan inceleyenler test kusurunun üzerinden geçmiş.
  • Beş eksenin beşinde de okunmamış öbekte kaçan 0’dır: bu ölçekte kaçan her kusurun tek nedeni bakılmayan eksendir. “Tamamını okudum” cümlesi “tamamına baktım” anlamına gelmez.
  • Test ekseni kapatıldığında bulunan 22’den 19’a iner, kaçan 2’den 5’e çıkar; kaçan üç kusur ayrıca testin delil rolünü zayıflatır.
  • Test gövdeyle aynı anda ve aynı anlayışla yazıldığı için testin geçmesi bağımsız bir delil değildir; test ekseni testin ne iddia ettiğine bakar, geçip geçmediğine değil.

Sonraki Adım

Buraya kadar üç eksen ölçüldü ve üçünün de nesnesi koddu: imza, gövde, test. Dördüncü eksenin nesnesi kodun dışındadır — değişikliğin belgeye yansıması. Bu eksen kapatıldığında da kaybın sınıf büyüklüğü kadar olması beklenir; ama belge ekseninin ayrı bir yanı var. Yazılmış bir belgenin yanlış olması ile bir davranışın hiç belgelenmemiş olması aynı şey değildir ve ikisi kurguda ayrı sınıflara düşer. Sonraki ders beş ekseni tek tek kapatarak kaybı ölçer ve belge ekseninin bulabildiği ile bulamadığını ayırır.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat