Ders 07 / 12
Kara, Beyaz ve Gri Kutu
Testin hangi bilgiye dayanarak yazıldığı ayrımı; belirtim tabanlı testin eksik işlevi, yapı tabanlı testin belgelenmemiş dalı bulması ve iki yaklaşımın dal kapsamıyla karşılaştırılması.
İçindekiler
Önceki ders testin nereye kadar uzandığını sordu. Bağımsız ikinci bir soru daha vardır: testi yazan kişi neye bakarak yazdı? Oradaki üç test de belirtimden türetilmişti — üst sınır kuralı okunup sorulmuştu. Kodun içine bakılarak yazılsalardı başka sorular çıkardı, çünkü kodda belirtimde hiç bulunmayan yollar olabilir.
Bu ders o bilgi düzeyi ayrımını kurar ve iki yaklaşımın farklı türde kusur bulduğunu aynı işlev üzerinde gösterir.
Bilgi Düzeyi Ayrımı
Kara kutu testi (black-box testing) yalnız dışarıdan görüneni kullanır: belirtim, arayüz, girdi ve çıktı. Kodun nasıl yazıldığı bilinmez. Bu yüzden belirtim tabanlı test (specification-based testing) olarak da anılır.
Beyaz kutu testi (white-box testing) kaynak koda bakarak yazılır: hangi koşullar var, hangi dallar var, hangi döngü sınırları var? Yapı tabanlı test (structure-based testing) adı bu bakışı daha iyi anlatır — ölçütü programın yapısıdır.
Gri kutu testi (grey-box testing) ikisinin arasındadır. Kaynak kod okunmaz, ama iç yapının bir bölümü bilinir: veri şeması, kayıt biçimi, günlük kayıtları, hata kodları. Bu kısmi bilgi girdi seçimini yönlendirir.
Ayrım seviyeden bağımsızdır. Bir birim testi kara kutu da yazılabilir beyaz kutu da; bir sistem testi için de aynısı geçerlidir.
İzli Ücret Hesabı
Karşılaştırmanın ölçülebilir olması için ücret hesabı, hangi dalların çalıştığını kaydeden
bir biçimde yazılır. IZ kümesi çalışan dalların numarasını tutar.
// ucret-izli.mjs — hangi dallarin calistigini kaydeden ucret hesabi export const DALLAR = ['D1', 'D2', 'D3', 'D4']; export const IZ = new Set(); export function gecikmeUcreti(gecikmeGun, uyeNo, subeDisi = false) { if (uyeNo === 0) { IZ.add('D1'); return 0; } IZ.add('D2'); let ucret = Math.max(gecikmeGun - 3, 0) * 2; if (ucret > 20) { IZ.add('D3'); ucret = 20; } else { IZ.add('D4'); } return ucret; }
Belirtim dört madde içerir: ilk üç gün ücretsizdir, sonraki her gün 2 birimdir, ücret 20 birimi aşmaz ve şube dışı iadede 5 birim ek ücret alınır. Son madde kütüphanenin yeni kararıdır ve K12 numarasını taşır.
Kara Kutu Ne Bulur
Kara kutu denetimleri yalnız bu dört maddeden türetilir. Kodun içindeki uyeNo koşulu
bilinmediği için hiçbir denetim onu hedeflemez.
// kara-kutu.mjs — yalnizca belirtimden turetilen denetimler import assert from 'node:assert/strict'; import { gecikmeUcreti, DALLAR, IZ } from './ucret-izli.mjs'; const DENETIMLER = { 'K7a ilk 3 gun ucretsiz': () => assert.equal(gecikmeUcreti(3, 41), 0), 'K7b gun basina 2 birim': () => assert.equal(gecikmeUcreti(6, 41), 6), 'K7c ucret 20 birimi asmaz': () => assert.equal(gecikmeUcreti(100, 41), 20), 'K12 sube disi iadede 5 birim ek ucret': () => assert.equal(gecikmeUcreti(4, 41, true), 7), }; let gecen = 0; const dusen = []; for (const [ad, denetim] of Object.entries(DENETIMLER)) { try { denetim(); gecen += 1; } catch { dusen.push(ad); } } console.log(`kara kutu : ${gecen}/${Object.keys(DENETIMLER).length} denetim gecti`); for (const ad of dusen) console.log(` dusen: ${ad}`); console.log(`dal kapsami: ${IZ.size}/${DALLAR.length} dal calisti`); console.log(` ulasilmayan: ${DALLAR.filter((d) => !IZ.has(d)).join(', ')}`);
kara kutu : 3/4 denetim gecti dusen: K12 sube disi iadede 5 birim ek ucret dal kapsami: 3/4 dal calisti ulasilmayan: D1
Kara kutu, kodda hiç bulunmayan bir işlevi buldu: şube dışı iade kuralı belirtimde vardır, uygulamada yoktur. Beyaz kutu bu kusuru yapısı gereği bulamaz — var olmayan bir dala test yazılamaz. Eksik işlev yalnız belirtimle karşılaştırarak görülür.
Çıktının son satırı ise kara kutunun körlüğünü gösterir: dört daldan biri hiç çalışmadı. Belirtimde karşılığı olmayan bir dal, belirtimden türetilen hiçbir denetimin hedefi değildir. Dal kapsamı (branch coverage) ölçümünün buradaki işlevi, kusuru bulmak değil, kimsenin bakmadığı bölgeyi adlandırmaktır.
Beyaz Kutu Ne Bulur
Kaynak koda bakan kişi D1 dalını görür ve doğrudan onu hedefleyen bir denetim yazar.
// beyaz-kutu.mjs — kaynak koddan gorulen ulasilmayan dali hedefleyen denetim import assert from 'node:assert/strict'; import { gecikmeUcreti, DALLAR, IZ } from './ucret-izli.mjs'; const ucret = gecikmeUcreti(100, 0); try { assert.ok(ucret === 20, `uye numarasi 0 icin ucret ${ucret}, beklenen 20`); console.log('D1 denetimi: gecti'); } catch (hata) { console.log(`D1 denetimi: dustu — ${hata.message}`); } console.log(`dal kapsami: ${IZ.size}/${DALLAR.length} dal calisti`);
D1 denetimi: dustu — uye numarasi 0 icin ucret 0, beklenen 20 dal kapsami: 1/4 dal calisti
Bulunan şey bir işlem kısayoludur: sıfır numaralı üyeye hiç ücret yansıtılmaz. Böyle bir dal genellikle bir deneme sırasında eklenip kaldırılmayı unutan koddur; belirtimde bulunmadığı için hiçbir kara kutu denetimi onu sormaz ve ürüne sessizce yerleşir.
Aynı çıktının ikinci satırı beyaz kutunun kendi körlüğünü gösterir. Tek bir dalı hedefleyen küme yalnız o dalı çalıştırır; yapıya bakarak yazılan testler kodun var olan yollarını kapsar, kodun eksik yollarını değil. Yapıyı ölçüt alan bir çalışma, hiç yazılmamış bir kuralı hiçbir zaman aramaz.
Gri Kutu Aradaki Bilgiyi Kullanır
Gri kutu yaklaşımında kaynak kod okunmaz, ama üye kayıtlarının şeması bilinir: üye numarası sıfırdan başlayan bir tam sayıdır. Bu bilgi, girdi seçimini yönlendirmeye yeter.
// gri-kutu.mjs — veri semasi bilgisinden turetilen yoklamalar import { gecikmeUcreti, DALLAR, IZ } from './ucret-izli.mjs'; const UYE_NO_ARALIGI = { enKucuk: 0, enBuyuk: 9999 }; const GECIKME_ORNEKLERI = [0, 4, 100]; const kusurlu = []; for (const uyeNo of [UYE_NO_ARALIGI.enKucuk, UYE_NO_ARALIGI.enBuyuk]) { for (const gun of GECIKME_ORNEKLERI) { const beklenen = Math.min(Math.max(gun - 3, 0) * 2, 20); const gozlenen = gecikmeUcreti(gun, uyeNo); if (gozlenen !== beklenen) kusurlu.push(`uyeNo=${uyeNo} gun=${gun}: ${gozlenen} (beklenen ${beklenen})`); } } console.log(`gri kutu : ${kusurlu.length} sapma bulundu`); for (const s of kusurlu) console.log(` ${s}`); console.log(`dal kapsami: ${IZ.size}/${DALLAR.length} dal calisti`);
gri kutu : 2 sapma bulundu uyeNo=0 gun=4: 0 (beklenen 2) uyeNo=0 gun=100: 0 (beklenen 20) dal kapsami: 4/4 dal calisti
Şema bilgisi kaynak koda erişim vermez; yalnız hangi girdilerin sınır olduğunu söyler. Sıfırın bir üye numarası aralığının alt ucu olduğunu bilmek, o değeri denemeye yeter ve belgelenmemiş dal kaynak koda hiç bakılmadan ortaya çıkar. Dört dalın dördü de çalıştı.
Hangi Yaklaşım Ne Zaman
Üç yaklaşım birbirinin yerine geçmez, farklı boşlukları kapatır.
Kara kutu, belirtimle ürün arasındaki farkı bulur ve kodun değişmesinden etkilenmez; kod yeniden düzenlendiğinde bu testler ayakta kalır. Kabul seviyesinde ve dış arayüzlerde tek geçerli yaklaşım budur, çünkü ölçüt kullanıcının gördüğüdür.
Beyaz kutu, belirtimde karşılığı olmayan yolları bulur ve kapsam boşluklarını adlandırır. Bedeli, kodun yapısına bağlanmasıdır: yapı değiştiğinde testin kendisi de değişir.
Gri kutu, dış arayüzden çalışırken iç bilgiyi girdi seçiminde kullanır. Uygulamada en sık karşılaşılan durum budur; testi yazan kişi çoğu zaman şemayı, hata kodlarını ve günlük kayıtlarını bilir.
Pratik ölçüt şudur: denetimlerin gövdesi belirtimden yazılır, kapsam ölçümü yapıdan okunur. Kapsam boşluğu görüldüğünde sorulacak soru “buraya test yazayım mı” değil, “bu dalın belirtimde karşılığı var mı” olmalıdır. Karşılığı yoksa yazılacak şey test değil, o dalın kaldırılmasıdır.
Özet
- Kara kutu belirtime, beyaz kutu kaynak kodun yapısına, gri kutu şema ve kayıt biçimi gibi kısmi iç bilgiye dayanır; ayrım test seviyesinden bağımsızdır.
- Kara kutu kodda hiç bulunmayan işlevi bulur; beyaz kutu var olmayan dala test yazamadığı için bu kusuru göremez.
- Beyaz kutu belirtimde karşılığı olmayan dalları bulur; örnekte sıfır numaralı üyeye ücret yansıtmayan belgelenmemiş kısayol böyle ortaya çıktı.
- Dal kapsamı ölçümü kusur bulmaz; kimsenin bakmadığı bölgeyi adlandırır.
- Kapsam boşluğunun doğru sorusu “test yazayım mı” değil, “bu dalın belirtimde karşılığı var mı” sorusudur.
Sonraki Adım
Seviye ve bilgi düzeyi bir testin yerini belirler, amacını belirlemez. Aynı kara kutu birim testi, sürümün ayakta olup olmadığını anlamak için de koşturulabilir, giderilmiş bir kusurun geri gelip gelmediğini denetlemek için de. İkisinde de test aynıdır; değişen şey neden koşturulduğu ve sonucundan ne yapılacağıdır. Sonraki ders testleri bu amaca göre adlandırır: duman, sağlık, gerileme ve kabul.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.