Ders 03 / 13
Test Adlandırma
Test adının birim, koşul ve beklenen sonuç parçalarından kurulması, üç kuralı tek testte toplamanın adı yalancı kılması ve geçen testlerin adlarının okunabilir bir kural listesi oluşturması.
İçindekiler
Düşen bir koşumun ilk verdiği bilgi iddia değil, addır. Koşucunun bildirdiği satırda önce sonuç, sonra testin adı gelir; ayrıntılı hata iletisi bunun altındadır. Ad kuralı söylüyorsa okuyan çoğu zaman kaynağa gitmeden ne bozulduğunu bilir. Ad “kayıt doğru” gibi bir şey söylüyorsa, hata iletisini okumak ve oradan kaynağa gitmek zorunludur.
Bu ders adı bir biçim sorunu olmaktan çıkarıp ölçülebilir bir şeye bağlar: aynı üç kural iki farklı biçimde yazıldığında, düşen koşumun verdiği bilgi ne kadar değişir?
Adın Üç Parçası
İyi bir test adı bir cümledir ve üç parça taşır: hangi birim, hangi koşul altında, hangi sonucu verir. Üçü de bulunduğunda ad tek başına okunabilir bir kuraldır.
ogrenci oduncu yirmi sekiz gun surer cümlesinde birim ödünç süresi hesabıdır, koşul üye
türünün öğrenci olmasıdır, sonuç yirmi sekiz gündür. Buna karşılık sonTarih testi
adında ne koşul ne de sonuç vardır; dogru calisir adında ise birim de yoktur.
İki uygulama kuralı bu biçimi korur. Ad sınanan işlevin içindeki adımlara değil,
dışarıdan gözlenen davranışa atıf yapar: Math.min cagrilir bir gerçekleştirim ayrıntısı,
ust siniri asamaz bir davranıştır. Ad olumsuzlama yerine olumlu bir kural bildirir:
hata vermez yerine sinir icindeki oduncu kabul eder.
Tek Testte Üç Kural
Aşağıdaki kitaplık sürümünde üç kural birden gerilemiştir: öğrenci ödünç süresi on dört güne düşmüş, ücretsiz gün payı sıfırlanmış ve gecikme ücretinin üst sınırı kaldırılmıştır.
// kural.mjs — gerilemis surum: uc kural birden bozuk export const KURALLAR = { ogrenci: { oduncGun: 14, enCokOdunc: 10 }, uye: { oduncGun: 14, enCokOdunc: 5 }, }; export const GECIKME = { ucretsizGun: 0, gunlukUcret: 2, ustSinir: 40 }; export function sonTarih(alisGunu, uyeTuru) { return alisGunu + KURALLAR[uyeTuru].oduncGun; } export function gecikmeUcreti(sonGun, iadeGunu) { const gecikme = iadeGunu - sonGun; if (gecikme <= GECIKME.ucretsizGun) return 0; return (gecikme - GECIKME.ucretsizGun) * GECIKME.gunlukUcret; }
Üç kuralı tek testte toplayan biçim, adında ancak genel bir şey söyleyebilir.
// toplu.test.mjs — uc kurali tek testte dogrulayan bicim import { test } from 'node:test'; import assert from 'node:assert/strict'; import { sonTarih, gecikmeUcreti } from './kural.mjs'; test('odunc kurallari dogru calisir', () => { assert.equal(sonTarih(1000, 'ogrenci'), 1028); assert.equal(gecikmeUcreti(1000, 1003), 0); assert.equal(gecikmeUcreti(1000, 1100), 40); });
node --test --test-reporter=tap toplu.test.mjs | grep -E '^ *(ok|not ok|# (tests|pass|fail))'
not ok 1 - odunc kurallari dogru calisir # tests 1 # pass 0 # fail 1
Üç kural bozuk, rapor bir satır. Bunun nedeni yalnız adlandırma değildir: bir iddia düştüğünde testin geri kalanı hiç çalışmaz. İkinci ve üçüncü iddia hiç değerlendirilmedi, dolayısıyla o iki kuralın durumu bilinmiyor. Düzeltme yapıldıkça aynı test yeniden düşer ve her seferinde bir sonraki kural ortaya çıkar.
Aynı üç kuralın ayrı testlere bölünmüş biçimi farklı bir rapor üretir.
// ayrik.test.mjs — ayni uc kural, ucu ayri testte import { test } from 'node:test'; import assert from 'node:assert/strict'; import { sonTarih, gecikmeUcreti } from './kural.mjs'; test('ogrenci oduncu yirmi sekiz gun surer', () => { assert.equal(sonTarih(1000, 'ogrenci'), 1028); }); test('ucretsiz gun payi icindeki iade ucretsizdir', () => { assert.equal(gecikmeUcreti(1000, 1003), 0); }); test('gecikme ucreti ust siniri asmaz', () => { assert.equal(gecikmeUcreti(1000, 1100), 40); });
node --test --test-reporter=tap ayrik.test.mjs | grep -E '^ *(ok|not ok|# (tests|pass|fail))'
not ok 1 - ogrenci oduncu yirmi sekiz gun surer not ok 2 - ucretsiz gun payi icindeki iade ucretsizdir not ok 3 - gecikme ucreti ust siniri asmaz # tests 3 # pass 0 # fail 3
Aynı kod, aynı üç kural, aynı üç iddia. Fark ölçülebilir: birinci biçim bir kuralın bozulduğunu, ikinci biçim üç kuralın bozulduğunu ve hangileri olduğunu bildirdi. Kaynağa bakmadan elde edilen bilgi üçe katlandı.
Bu, ikinci dersteki sinyal gücü ölçümünün eşlik eden yarısıdır. Orada iddianın kaç bozulmayı yakaladığı ölçüldü; burada yakalanan bozulmanın rapora ne kadarının ulaştığı ölçülüyor. Bir testin bir davranışı doğrulaması kuralı bu iki ölçümün ortak sonucudur, estetik bir tercih değil.
Adların Toplamı Bir Belirtimdir
Kurallar düzeltildiğinde geçen testlerin listesi başka bir işe yarar: kitaplığın davranışını okunabilir biçimde anlatır.
// kural.mjs — duzeltilmis surum export const KURALLAR = { ogrenci: { oduncGun: 28, enCokOdunc: 10 }, uye: { oduncGun: 14, enCokOdunc: 5 }, }; export const GECIKME = { ucretsizGun: 3, gunlukUcret: 2, ustSinir: 40 }; export function sonTarih(alisGunu, uyeTuru) { return alisGunu + KURALLAR[uyeTuru].oduncGun; } export function gecikmeUcreti(sonGun, iadeGunu) { const gecikme = iadeGunu - sonGun; if (gecikme <= GECIKME.ucretsizGun) return 0; const ham = (gecikme - GECIKME.ucretsizGun) * GECIKME.gunlukUcret; return Math.min(ham, GECIKME.ustSinir); }
Testleri konu başlıklarına gruplamak, adın taşıması gereken yükü paylaştırır: birim ve bağlam gruba, koşul ve sonuç teste kalır.
// belirtim.test.mjs — adlari kural listesi olarak okunan test kumesi import { describe, test } from 'node:test'; import assert from 'node:assert/strict'; import { sonTarih, gecikmeUcreti } from './kural.mjs'; describe('odunc suresi', () => { test('ogrenci uyede yirmi sekiz gundur', () => { assert.equal(sonTarih(1000, 'ogrenci'), 1028); }); test('standart uyede on dort gundur', () => { assert.equal(sonTarih(1000, 'uye'), 1014); }); }); describe('gecikme ucreti', () => { test('ucretsiz gun payi icinde sifirdir', () => { assert.equal(gecikmeUcreti(1000, 1003), 0); }); test('ucretsiz gun payi disinda gun basina ucretlendirilir', () => { assert.equal(gecikmeUcreti(1000, 1008), 10); }); test('ust siniri asamaz', () => { assert.equal(gecikmeUcreti(1000, 1100), 40); }); });
node --test --test-reporter=tap belirtim.test.mjs | grep -E '^ *(ok|not ok|# (tests|pass|fail))'
ok 1 - ogrenci uyede yirmi sekiz gundur
ok 2 - standart uyede on dort gundur
ok 1 - odunc suresi
ok 1 - ucretsiz gun payi icinde sifirdir
ok 2 - ucretsiz gun payi disinda gun basina ucretlendirilir
ok 3 - ust siniri asamaz
ok 2 - gecikme ucreti
# tests 5
# pass 5
# fail 0
Girintili satırlar tek tek kuralları, girintisiz satırlar grupları verir. Çıktı yukarıdan aşağıya okunduğunda ortaya bir kural listesi çıkar: ödünç süresi öğrenci üyede yirmi sekiz, standart üyede on dört gündür; gecikme ücreti ücretsiz gün payı içinde sıfırdır, dışında gün başına ücretlendirilir ve üst sınırı aşamaz.
Bu liste yazılı belirtimin kendisi değildir, ama onunla karşılaştırılabilir. Belirtimde olup listede olmayan bir kural, birinci derste anılan izlenebilirlik boşluğudur. Listede olup belirtimde olmayan bir satır ise ters yönde bir uyarıdır: ya belirtim eksik yazılmış ya da test, kimsenin istemediği bir davranışı sabitlemiştir.
Ad ile İddianın Uyumu
Ad ile iddia arasında tek bir tutarlılık kuralı vardır: iddiada geçen her alan, adın
söylediği kuralın parçası olmalıdır. ogrenci uyede yirmi sekiz gundur adlı bir test
ayrıca kaydın durum alanını da denetliyorsa, o test iki kural sınıyor ve adı ikincisini
gizliyor demektir.
Ters yönü de aynı ölçüde bağlayıcıdır: adın söylediği kural iddiada geçmiyorsa test adını yerine getirmiyordur. İkinci dersteki eşleştirmesiz hata beklentisi bunun bir örneğiydi — adı ödünç sınırından söz ediyordu, gerçekte sınadığı şey ise eksik bir alandı.
Ad değişmeden iddia genişlediğinde bu uyum sessizce bozulur. Bir teste yeni bir iddia eklenirken sorulacak soru şudur: bu iddia mevcut adın kapsamında mı, yoksa yeni bir test mi gerekiyor? İkinci yanıt çoğu zaman doğru olandır ve maliyeti üç satırdır.
Özet
- Test adı birim, koşul ve beklenen sonuç parçalarını taşır; üçü bulunduğunda ad tek başına okunabilir bir kuraldır.
- Ad, gerçekleştirim adımlarına değil dışarıdan gözlenen davranışa atıf yapar ve olumsuzlama yerine olumlu kural bildirir.
- Bir iddia düştüğünde testin kalan iddiaları hiç çalışmaz; üç kuralı tek teste toplayan biçim bir düşüş, ayrılmış biçim üç düşüş bildirdi.
- Geçen testlerin adları yukarıdan aşağıya okunduğunda bir kural listesi verir; bu liste yazılı belirtimle karşılaştırılabilir.
- İddiada geçen her alan adın kapsamında olmalıdır; ad değişmeden iddia genişlediğinde test adının söylemediği bir kuralı sınamaya başlar.
Sonraki Adım
Buraya kadar her test yalnız kendi girdisine baktı ve her koşum aynı sonucu verdi. Testler çoğaldıkça bu durum kendiliğinden sürmez: ortak bir düzeneği paylaşan iki test birbirinin bıraktığı durumu görür ve koşum sırası sonucu belirlemeye başlar. Sonraki ders bu bağı gerçek bir koşumla üretir — aynı testler farklı sırada farklı sonuç verir — ve testleri hızlı ve birbirinden bağımsız tutan düzeneği kurar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.