---
title: 'Kalite Nitelikleri'
source: 'https://academia.sh/tr/kurslar/test-temelleri/kalite-nitelikleri'
course: 'Kalite ve Test Temelleri'
language: tr
updated: '2026-08-17T18:10:53+00:00'
license: 'CC BY-SA 4.0'
---

# Kalite Nitelikleri

İşlevsel beklentiler ile kalite niteliklerinin ayrılması, nitelik ailelerinin sınıflandırılması ve ölçülemez bir beklentinin uyaran-ortam-yanıt-ölçüt biçiminde ölçülebilir bir ölçüte çevrilmesi.

Önceki ders ücret hesabının doğru sonucu vermesini konu aldı. Doğru sonuç, beklentilerin
yalnız bir bölümüdür. Kitaplık doğru ücreti hesaplayıp da raporu dakikalarca ürettiğinde,
bir üyenin borcunu başka bir üyeye gösterdiğinde ya da bozuk tek bir kayıt yüzünden hiç
çalışmadığında kullanılamaz. Bu beklentiler belirtimde çoğu zaman yazılı değildir; yazılı
olduklarında da "hızlı olsun", "sağlam olsun" gibi sınanamaz cümlelerle geçer.

Bu ders o cümleleri adlandırır ve sınanabilir hâle getirir. Sınanabilir olmanın ölçütü
tektir: bir beklenti, geçip geçmediğine bakılabilen bir ölçüte çevrilebiliyorsa
sınanabilir.

## İşlevsel Beklenti ve Kalite Niteliği

**İşlevsel beklenti** (functional requirement) sistemin **ne yaptığını** söyler: dört gün
geciken kitaptan 2 birim ücret alınır, bilinmeyen üye türü reddedilir. Doğru ya da yanlış
biçiminde yanıtlanır; ara değeri yoktur.

**Kalite niteliği** (quality attribute) sistemin o işi **nasıl yaptığını** söyler: ne kadar
hızlı, ne kadar dayanıklı, ne kadar güvenli, ne kadar değiştirilebilir. Yanıtı derecelidir
ve bir eşikle birlikte anlam kazanır. Bu yüzden nitelikler için doğruluk değil, **bütçe**
konuşulur.

Ayrım tek başına bir sınıflandırma alıştırması değildir; iki beklenti türü farklı biçimde
sınanır. İşlevsel beklenti tek bir girdi–çıktı çiftiyle sınanabilir. Nitelik ise ancak bir
ölçüm düzeneği, bir yük ve bir eşikle sınanır.

## Nitelik Aileleri

Nitelikler adlandırılmadığında konuşulamaz. Sık kullanılan aileler ve kitaplık bağlamındaki
karşılıkları şunlardır:

| Nitelik ailesi | İngilizce | Kitaplıktaki sorusu |
|---|---|---|
| işlevsel uygunluk | functional suitability | Ücret hesabı kurala uyuyor mu? |
| başarım verimliliği | performance efficiency | Rapor ne kadar sürede çıkıyor? |
| güvenilirlik | reliability | Bozuk kayıt geldiğinde ne oluyor? |
| kullanılabilirlik | usability | Görevli borcu kaç adımda görüyor? |
| güvenlik | security | Bir üyenin borcu başkasına görünüyor mu? |
| sürdürülebilirlik | maintainability | Ücret kuralı kaç yerden değişiyor? |
| taşınabilirlik | portability | Başka bir çalışma zamanında kuruluyor mu? |
| uyumluluk | compatibility | Eski kayıt biçimi okunabiliyor mu? |

Liste kapalı değildir; her alanın kendi ekleri olur. Önemli olan, bir beklentinin hangi
aileye girdiğinin sorulmasıdır — çünkü aile, ölçünün nasıl kurulacağını belirler.

## Ölçülemez Beklentiyi Ölçüte Çevirmek

"Rapor hızlı olsun" cümlesi sınanamaz, çünkü ne kadar hızlı, hangi yükte, hangi ortamda
sorularının yanıtı yoktur. Bu boşluğu dolduran biçim dört parçalıdır ve **nitelik senaryosu**
(quality attribute scenario) olarak bilinir:

- **Uyaran** (stimulus): görevli borçlu üye raporunu ister.
- **Ortam** (environment): kitaplıkta 8.000 üye ve 80.000 ödünç kaydı vardır, sistem
  olağan yükte çalışmaktadır.
- **Yanıt** (response): rapor her üyenin toplam gecikme borcunu üretir.
- **Yanıt ölçütü** (response measure): beş koşunun ortancası 100 milisaniyeyi geçmez.

Dördüncü parça beklentiyi sınanabilir kılan parçadır. Frontend Kalitesi kursundaki Başarım
Bütçesi dersinde kurulan bütçe düşüncesi burada alan bağımsız hâliyle kullanılır: ölçüt bir
sayı, bir yük ve bir ölçüm yöntemiyle birlikte yazılır.

## Ölçütü Ölçmek

Ölçüt yazıldıysa ölçülebilir. Rapor iki biçimde yazılır: her üye için bütün ödünç kayıtlarını
tarayan sürüm ve kayıtları bir kez gezip üye numarasına göre toplayan sürüm.

```js
// rapor.mjs — borclu uye raporunun iki uygulamasi
export function veriUret(uyeSayisi, oduncSayisi) {
  const uyeler = Array.from({ length: uyeSayisi }, (_, i) => ({ no: i, tur: i % 3 === 0 ? 'ogrenci' : 'uye' }));
  const oduncler = Array.from({ length: oduncSayisi }, (_, i) => ({
    uyeNo: (i * 7919) % uyeSayisi,
    gecikmeGun: i % 47,
  }));
  return { uyeler, oduncler };
}

function ucret(gecikmeGun) {
  return Math.min(Math.max(gecikmeGun - 3, 0) * 2, 20);
}

export function raporTaramali(uyeler, oduncler) {
  return uyeler.map((u) => {
    let borc = 0;
    for (const o of oduncler) if (o.uyeNo === u.no) borc += ucret(o.gecikmeGun);
    return { no: u.no, borc };
  });
}

export function raporDizinli(uyeler, oduncler) {
  const borclar = new Map();
  for (const o of oduncler) borclar.set(o.uyeNo, (borclar.get(o.uyeNo) ?? 0) + ucret(o.gecikmeGun));
  return uyeler.map((u) => ({ no: u.no, borc: borclar.get(u.no) ?? 0 }));
}
```

İki sürüm de aynı işlevsel gereksinimi karşılar; ürettikleri rapor birebir aynıdır. Ayrıldıkları
yer nitelik ölçütüdür.

```js
// olcum.mjs — yanit suresi olcutunun olculmesi
import { veriUret, raporTaramali, raporDizinli } from './rapor.mjs';

const BUTCE_MS = 100;
const { uyeler, oduncler } = veriUret(8000, 80000);

function ortancaSure(islev, kosu = 5) {
  const sureler = [];
  for (let i = 0; i < kosu; i += 1) {
    const bas = performance.now();
    islev(uyeler, oduncler);
    sureler.push(performance.now() - bas);
  }
  sureler.sort((a, b) => a - b);
  return sureler[Math.floor(kosu / 2)];
}

for (const [ad, islev] of [['taramali', raporTaramali], ['dizinli', raporDizinli]]) {
  const ortanca = ortancaSure(islev);
  const yargi = ortanca < BUTCE_MS ? 'gecti' : 'kaldi';
  console.log(`${ad.padEnd(9)}: ${BUTCE_MS} ms butcesi — ${yargi}`);
}
```

```
taramali : 100 ms butcesi — kaldi
dizinli  : 100 ms butcesi — gecti
```

Çıktı ham süreyi değil yargıyı yazar; ham süre makineye bağlıdır ve bir dersten diğerine
taşınamaz. Bu metni hazırlarken kullanılan makinede tarama sürümünün ortancası 548,6 ms,
dizinli sürümünkü 2,7 ms ölçüldü — iki sayı da çalıştırıldığı donanıma ve çalışma zamanı
sürümüne göre değişir. Değişmeyen şey, ölçütün iki sürümü ayırmasıdır: bütçe belirlendikten
sonra "hızlı mı" sorusunun yanıtı tartışma konusu olmaktan çıkar.

Ölçümün tek koşuya değil beş koşunun ortancasına dayanması bilinçlidir. İlk koşu çalışma
zamanının ısınma etkisini taşır; ortanca bu sıçramayı dışarıda bırakır.

## İkinci Bir Nitelik: Güvenilirlik

Başarım tek nitelik değildir ve her nitelik kendi ölçüsünü ister. Güvenilirlik senaryosu
şöyle yazılır: kayıtların bir bölümü bozuk geldiğinde rapor durmaz, bozuk kaydı atlar ve
atlanan oranı bildirir; oran yüzde beşi aşarsa rapor geçersiz sayılır.

```js
// dayaniklilik.mjs — guvenilirlik olcutunun olculmesi
import { veriUret } from './rapor.mjs';

const ESIK = 0.05;
const { oduncler } = veriUret(8000, 80000);
for (let i = 0; i < oduncler.length; i += 33) oduncler[i].gecikmeGun = -1;

let islenen = 0;
let atlanan = 0;
for (const o of oduncler) {
  if (!Number.isInteger(o.gecikmeGun) || o.gecikmeGun < 0) atlanan += 1;
  else islenen += 1;
}

const oran = atlanan / oduncler.length;
console.log(`islenen kayit: ${islenen}`);
console.log(`atlanan kayit: ${atlanan}`);
console.log(`atlanan orani: ${(oran * 100).toFixed(2)} (esik ${ESIK * 100})`);
console.log(`rapor durumu : ${oran <= ESIK ? 'gecerli' : 'gecersiz'}`);
```

```
islenen kayit: 77575
atlanan kayit: 2425
atlanan orani: 3.03 (esik 5)
rapor durumu : gecerli
```

Bu ölçüm süre içermediği için her makinede aynı sonucu verir. Nitelik ölçütlerinin hepsi
zamana bağlı değildir: oran, sayı, boyut ve adım sayısı da ölçüttür ve belirlenimci
oldukları için sınanmaları daha ucuzdur.

## Nitelikler Birbiriyle Yarışır

Dizinli sürüm süreyi kısalttı, ama bunu üye sayısı kadar girdi tutan bir eşleme kurarak
yaptı. Bellek tüketimi arttı. Bozuk kayıtları atlayan sürüm raporu ayakta tuttu, ama sessizce
eksik bir toplam üretti; doğruluk pahasına süreklilik satın alındı.

Bu genel bir durumdur: nitelikler birbirinden bağımsız artırılamaz. Başarım ile bellek,
güvenlik ile kullanılabilirlik, esneklik ile yalınlık çoğu zaman ters yönde çeker. Bu yüzden
nitelik kararları **ödünleşimdir** (trade-off) ve gerekçesiyle birlikte yazılmalıdır: hangi
nitelik hangi nitelik uğruna ne kadar bırakıldı? Bütçe yazmanın asıl işlevi burada görünür.
Bütçe, ödünleşimi bir kez tartışıp karara bağlar; sonraki her ölçüm o karara karşı yapılır.

## Özet

- İşlevsel beklenti sistemin ne yaptığını, kalite niteliği bunu nasıl yaptığını söyler;
  birincisi doğru-yanlış, ikincisi dereceli yanıtlanır.
- Bir nitelik beklentisi uyaran, ortam, yanıt ve yanıt ölçütü olarak yazıldığında sınanabilir
  hâle gelir; ölçütü olmayan beklenti sınanamaz.
- Aynı işlevi karşılayan iki uygulama aynı bütçeye karşı farklı sonuç verebilir; örnekte
  tarama sürümü 100 ms bütçesinde kaldı, dizinli sürüm geçti.
- Ölçüm süre içeriyorsa çıktıya ham süre değil yargı yazılır; ham süre makineye bağlıdır.
- Oran, sayı ve boyut ölçütleri belirlenimcidir ve süre ölçütlerinden ucuza sınanır.
- Nitelikler birbiriyle yarışır; bütçe, ödünleşimi bir kez karara bağlayıp sonraki ölçümlere
  ortak ölçüt verir.

## Sonraki Adım

İki derste de kusur, birinin onu araması sayesinde ortaya çıktı: gişe kayıtları
karşılaştırıldığı için, bütçe ölçüldüğü için. Kimse o karşılaştırmayı yapmasaydı iki kusur da
görünmeyecekti. Buradan bir soru doğar — kusuru arayan kişi neyi farklı yapar? Sonraki ders
testin bir teknikler kümesi olmadan önce bir tutum olduğunu ele alır: programın çalıştığını
göstermeye çalışan bakış ile kırıldığı yeri arayan bakış aynı koda bakıp farklı şeyler bulur.
