---
title: 'Test Tasarım Teknikleri'
source: 'https://academia.sh/tr/kurslar/test-temelleri/test-tasarim-teknikleri'
course: 'Kalite ve Test Temelleri'
language: tr
updated: '2026-08-17T18:10:53+00:00'
license: 'CC BY-SA 4.0'
---

# Test Tasarım Teknikleri

Sonsuz girdi uzayından sonlu denetim kümesi seçmenin sistemli yolları: denklik sınıfları, sınır değer analizi ve koşul birleşimlerini eksiksiz sayan karar tablosu.

Buraya kadar denetimlerin girdileri örnek olarak seçildi: 3 gün, 4 gün, 100 gün. Seçimin
gerekçesi sezgiydi ve sezgi tekrarlanabilir değildir — aynı işlevi iki kişi sınadığında iki
farklı küme çıkar, ikisinin de neyi kapsadığı belirsiz kalır.

Bu ders girdi seçimini gerekçelendirilebilir bir işleme dönüştürür. Üç teknik ele alınır:
aynı davranan girdileri sınıflara ayırmak, sınıfların kenarlarını yoklamak ve koşul
birleşimlerini eksiksiz saymak.

## Girdi Uzayı Sonsuz, Denetim Sayısı Sonlu

Birinci derste kurulan sınır burada işlerlik kazanır: test kusurun varlığını gösterebilir,
yokluğunu gösteremez, çünkü sonlu sayıda girdiyle sonsuz girdi kümesi denenemez. O hâlde
sorulacak soru "hepsi denendi mi" değil, "denenenler neyi temsil ediyor" olmalıdır.

Test tasarım teknikleri bu temsil ilişkisini kurar. Her teknik, girdi uzayını bir ölçüte
göre böler ve bölümlerden seçim yapmayı gerekçelendirir. Ölçüt yazılı olduğu için hangi
girdilerin **neden** seçildiği ve neyin dışarıda kaldığı da yazılı olur.

Örnek olarak ödünç verme kararı kullanılır. Karar üç kurala bağlıdır: kitap başkası adına
rezerve edilmişse verilmez, üyenin borcu sınıra ulaşmışsa verilmez, üyenin aktif ödünç
sayısı türünün sınırına ulaşmışsa verilmez.

```js
// karar.mjs — odunc kararinin uc kuralli uygulamasi
export const ODUNC_SINIRI = { ogrenci: 10, uye: 5 };
export const BORC_SINIRI = 20;

export function oduncKarari({ uyeTuru, aktifOdunc, borc, baskasinaRezerve }) {
  if (!(uyeTuru in ODUNC_SINIRI)) throw new Error(`bilinmeyen uye turu: ${uyeTuru}`);
  if (!Number.isInteger(aktifOdunc) || aktifOdunc < 0) throw new Error('aktif odunc gecersiz');
  if (baskasinaRezerve) return 'rezerve';
  if (borc > BORC_SINIRI) return 'borc';
  if (aktifOdunc >= ODUNC_SINIRI[uyeTuru]) return 'sinir';
  return 'verildi';
}
```

## Denklik Sınıfları

**Denklik sınıfı** (equivalence class), programın aynı biçimde işlediği girdilerden oluşan
kümedir. Varsayım şudur: bir sınıfın bir üyesi kusuru ortaya çıkarıyorsa, aynı sınıfın
diğer üyeleri de çıkarır. Bu varsayım doğruysa sınıf başına bir temsilci yeterlidir.

Borç değeri iki sınıfa ayrılır: sınırın altındakiler ve sınıra ulaşanlar. Aktif ödünç sayısı
da aynı biçimde ikiye ayrılır. Rezerve durumu zaten iki değerlidir.

```js
// siniflar.mjs — her denklik sinifindan bir temsilci
import { oduncKarari } from './karar.mjs';

const temel = { uyeTuru: 'uye', aktifOdunc: 2, borc: 8, baskasinaRezerve: false };
const TEMSILCILER = [
  ['borc sinifi: sinir alti', { borc: 8 }, 'verildi'],
  ['borc sinifi: sinir ustu', { borc: 35 }, 'borc'],
  ['odunc sinifi: sinir alti', { aktifOdunc: 2 }, 'verildi'],
  ['odunc sinifi: sinir ustu', { aktifOdunc: 7 }, 'sinir'],
  ['rezerve: yok', { baskasinaRezerve: false }, 'verildi'],
  ['rezerve: var', { baskasinaRezerve: true }, 'rezerve'],
];

let gecen = 0;
for (const [ad, degisiklik, beklenen] of TEMSILCILER) {
  const gozlenen = oduncKarari({ ...temel, ...degisiklik });
  if (gozlenen === beklenen) gecen += 1;
  else console.log(`  sapma: ${ad} — beklenen ${beklenen}, gozlenen ${gozlenen}`);
}
console.log(`denklik siniflari: ${gecen}/${TEMSILCILER.length} temsilci uyustu`);
```

```
denklik siniflari: 6/6 temsilci uyustu
```

Altı temsilcinin altısı da uyuştu. Tekniğin getirisi burada görülür: on binlerce olası borç
değeri yerine iki değer denendi ve her sınıfın kapsandığı yazılı hâle geldi.

Sınıflar ayrılırken iki tür ayrım yapılır. **Geçerli sınıf** (valid partition) programın
kabul etmesi gereken girdileri, **geçersiz sınıf** (invalid partition) reddetmesi gerekenleri
toplar — negatif ödünç sayısı ve bilinmeyen üye türü geçersiz sınıflardır. Geçersiz sınıflar
tek tek denenir; iki geçersiz değer aynı denetimde birleştirilirse ilk reddin ikincisini
gölgelemesi ve kusurun görünmez kalması olağandır.

## Sınır Değer Analizi

Denklik sınıfının varsayımı bir yerde zayıflar: sınıfların **kenarında**. Kusurların büyük
bölümü karşılaştırma operatörlerinde toplanır ve bir operatör hatası yalnız kenarda görünür
— sınıfın ortasından seçilen temsilci onu göremez.

**Sınır değer analizi** (boundary value analysis) her sınıf kenarı için üç değer üretir:
eşiğin bir altı, eşiğin kendisi ve bir üstü. Değerler elle değil, bildirilen eşiklerden
türetilir; eşik değiştiğinde denetimler de kendiliğinden değişir.

```js
// sinir.mjs — siniflarin kenarlarindan turetilen degerler
import { oduncKarari, ODUNC_SINIRI, BORC_SINIRI } from './karar.mjs';

const komsular = (esik) => [esik - 1, esik, esik + 1];
const temel = { uyeTuru: 'uye', aktifOdunc: 2, borc: 8, baskasinaRezerve: false };

const DENETIMLER = [
  ...komsular(BORC_SINIRI).map((borc) => ({
    ad: `borc=${borc}`, girdi: { borc }, beklenen: borc >= BORC_SINIRI ? 'borc' : 'verildi',
  })),
  ...komsular(ODUNC_SINIRI.uye).map((aktifOdunc) => ({
    ad: `aktifOdunc=${aktifOdunc}`, girdi: { aktifOdunc },
    beklenen: aktifOdunc >= ODUNC_SINIRI.uye ? 'sinir' : 'verildi',
  })),
];

let sapma = 0;
for (const d of DENETIMLER) {
  const gozlenen = oduncKarari({ ...temel, ...d.girdi });
  if (gozlenen !== d.beklenen) {
    sapma += 1;
    console.log(`  sapma: ${d.ad} — beklenen ${d.beklenen}, gozlenen ${gozlenen}`);
  }
}
console.log(`sinir degerleri: ${DENETIMLER.length} denetim, ${sapma} sapma`);
```

```
  sapma: borc=20 — beklenen borc, gozlenen verildi
sinir degerleri: 6 denetim, 1 sapma
```

Altı denetim, tek sapma. Borcu tam 20 birim olan üyeye ödünç veriliyor; kural "sınıra
ulaşan" derken uygulama "sınırı aşan" diyor. Bu kusur, sınıfların ortasından seçilen hiçbir
temsilciyle görünmezdi ve bir önceki kümede gerçekten de görünmedi.

Kaç değer denenmelidir? Üç değerli sınır (bir altı, eşik, bir üstü) yukarıdaki gibi bütün
operatör hatalarını yakalar. İki değerli sınır (eşik ve bir üstü) daha ucuzdur ve aynı
kusurların çoğunu bulur. Seçim, eşiğin taşıdığı riske göre yapılır — para, yetki ve süre
eşiklerinde üç değer tercih edilir.

## Karar Tablosu

Denklik sınıfları ve sınır değerleri girdileri **tek tek** ele alır. Kurallar birbirini
etkilediğinde bu yetmez: hangi koşul birleşimlerinin denendiği ve hangilerinin atlandığı
görünmez kalır.

**Karar tablosu** (decision table) koşulları satırlara, birleşimleri sütunlara yazar ve her
birleşimin hangi eylemi ürettiğini belirtir. Üç koşul sekiz birleşim demektir; sayım
programla yapıldığında hiçbiri atlanmaz.

```js
// karar-tablosu.mjs — uc kosulun butun birlesimlerinin sayilmasi ve kural birlestirme
const KOSULLAR = ['rezerve', 'borc', 'odunc'];

function eylem([rezerve, borc, sinir]) {
  if (rezerve) return 'rezerve';
  if (borc) return 'borc';
  if (sinir) return 'sinir';
  return 'verildi';
}

const birlesimler = [];
for (let i = 0; i < 2 ** KOSULLAR.length; i += 1) {
  const satir = KOSULLAR.map((_, j) => Boolean((i >> (KOSULLAR.length - 1 - j)) & 1));
  birlesimler.push({ satir, eylem: eylem(satir) });
}

console.log(`tam sayim: ${birlesimler.length} birlesim (${KOSULLAR.join(' / ')})`);
for (const b of birlesimler) {
  console.log(`  ${b.satir.map((v) => (v ? 'E' : 'H')).join(' ')} -> ${b.eylem}`);
}

const gruplar = new Map();
for (const b of birlesimler) {
  if (!gruplar.has(b.eylem)) gruplar.set(b.eylem, []);
  gruplar.get(b.eylem).push(b.satir);
}

console.log(`birlestirilmis kural sayisi: ${gruplar.size}`);
for (const [ey, satirlar] of gruplar) {
  const kural = KOSULLAR.map((_, j) => {
    const degerler = new Set(satirlar.map((s) => s[j]));
    return degerler.size === 1 ? ([...degerler][0] ? 'E' : 'H') : '-';
  });
  const kapsam = kural.reduce((n, k) => n * (k === '-' ? 2 : 1), 1);
  console.log(`  ${kural.join(' ')} -> ${ey.padEnd(7)} ${satirlar.length} birlesim, kural ${kapsam} birlesim kapsiyor`);
}
```

```
tam sayim: 8 birlesim (rezerve / borc / odunc)
  H H H -> verildi
  H H E -> sinir
  H E H -> borc
  H E E -> borc
  E H H -> rezerve
  E H E -> rezerve
  E E H -> rezerve
  E E E -> rezerve
birlestirilmis kural sayisi: 4
  H H H -> verildi 1 birlesim, kural 1 birlesim kapsiyor
  H H E -> sinir   1 birlesim, kural 1 birlesim kapsiyor
  H E - -> borc    2 birlesim, kural 2 birlesim kapsiyor
  E - - -> rezerve 4 birlesim, kural 4 birlesim kapsiyor
```

Sekiz birleşim dört kurala indi. `-` işareti **ilgisiz koşulu** (don't care) gösterir: kitap
başkası adına rezerve edilmişse borç ve ödünç sayısı sonucu değiştirmez, çünkü rezerve
denetimi diğerlerinden önce gelir. Birleştirmenin doğruluğu son sütunda sağlanır — kuralın
kapsadığı birleşim sayısı, gruptaki birleşim sayısına eşit olmalıdır.

Karar tablosunun asıl getirisi, kuralların **önceliğini** görünür kılmasıdır. Borcu sınırda
ve kitabı rezerve olan bir üyeye hangi yanıt verilecek? Tablo bu soruyu sormaya zorlar;
belirtim bunu yazmamışsa eksiklik tablo çizilirken ortaya çıkar. Denetim sayısı da kararlı
biçimde belirlenir: dört kural için dört denetim yeterlidir, sekiz denetim gereksizdir.

Koşul sayısı arttıkça birleşim sayısı iki katına çıkar; on koşul bin yirmi dört birleşim
demektir. Bu noktada tam sayım bırakılır ve her koşulun sonucu tek başına belirlediği
birleşimler seçilir. Seçim ölçütü değişir, tablonun kendisi değişmez.

## Tekniklerin İş Bölümü

Üç teknik aynı soruyu farklı yerlerden yanıtlar ve birbirinin yerine geçmez.

Denklik sınıfları girdi uzayını küçültür ve neyin temsil edildiğini yazılı kılar. Sınır
değerleri sınıfların kenarındaki kusurları yakalar — örnekte tek kusuru yalnız bu teknik
buldu. Karar tablosu koşul birleşimlerinin eksiksiz sayılmasını sağlar ve belirtimdeki
öncelik boşluklarını görünür yapar.

Sıralı davranışların kendi tekniği vardır: bir kaydın durumdan duruma geçişi söz konusuysa
denenmesi gereken şey değerler değil geçişlerdir. Bu teknik son derste ele alınır.

## Özet

- Test tasarım teknikleri girdi seçimini sezgiden çıkarıp gerekçelendirilebilir bir işleme
  çevirir; ölçüt yazılı olduğu için neyin dışarıda kaldığı da yazılı olur.
- Denklik sınıfı, programın aynı biçimde işlediği girdilerin kümesidir; sınıf başına bir
  temsilci varsayımı sınıfın ortasında geçerli, kenarında zayıftır.
- Geçersiz sınıflar tek tek denenir; birleştirildiklerinde ilk ret ikincisini gölgeler.
- Sınır değer analizi eşiğin bir altını, eşiği ve bir üstünü dener; örnekte borcu tam sınırda
  olan üyeye ödünç verildiği kusuru yalnız bu teknik buldu.
- Karar tablosu koşul birleşimlerini eksiksiz sayar, ilgisiz koşulları birleştirerek denetim
  sayısını düşürür ve belirtimdeki öncelik boşluklarını görünür kılar.

## Sonraki Adım

Teknikler hangi girdilerin deneneceğini belirledi. Denenen şeyin bir başkasına
anlatılabilmesi ayrı bir iştir: hangi durumda başlanacak, hangi adımlar izlenecek, ne
gözlenecek? Otomatik denetim bu bilgiyi kodun içinde taşır ve yalnız kodu okuyan kişiye
anlatır. Sonraki ders bu bilgiyi yazılı bir biçime kavuşturur ve o biçimden çalıştırılabilir
teste geçişi gösterir.
