---
title: 'Kullanıcı Kabul Testi'
source: 'https://academia.sh/tr/kurslar/test-sureci/kullanici-kabul-testi'
course: 'Test Süreci ve Otomasyon Altyapısı'
language: tr
updated: '2026-08-17T18:10:54+00:00'
license: 'CC BY-SA 4.0'
---

# Kullanıcı Kabul Testi

Son kullanıcı doğrulamasının bir dağıtım kararı olarak yönetilmesi: kabul kapsamının kullanıcı görevlerine dört ayrı bölünmesi, dönen geri bildirimin kusur ile istek ile yanlış anlama arasında ayrılması, her sınıfın dakikayla ölçülen bedeli ve geri bildirim hacminin neden bir kalite ölçüsü olmadığı.

Önceki dersin bütün ölçütlerini ekibin içindeki taraflar yazdı. Üçü de sistemi tasarlayan
tarafta duruyor ve aynı sözlüğü kullanıyor; oysa ölçütün sonunda karşılanması gereken beklenti
ekibin dışındadır. Kütüphane görevlisinin bir ödünç işlemini kaç adımda bitirmeyi beklediği ya
da bir üyenin gecikme bildirimini ne zaman anlamlı bulduğu hiçbir yuvaya yazılmadı.

**Kullanıcı kabul testi** (user acceptance testing) bu boşluğu son kullanıcıya sordurur. Bu
ders onu bir dağıtım kararı olarak kurar: dağıtılan kaynak kullanıcının zamanıdır, dağıtım
birimi **kullanıcı görevidir** ve dönen şey tek türden değildir. Geri bildirimin bir kısmı
kusurdur, bir kısmı yeni bir **istektir**, bir kısmı da sistemin doğru davranışını yanlış
okuyan bir **yanlış anlamadır** — ve üçünün bedeli farklıdır.

## Kabul Aşamasına Ne Ulaşır

Kabul testi son kapıdır: ondan önceki kapıların gördüğü kusur buraya gelmez. İkinci dersin
bütçeye sığan dokuz kalemi dokuz sınıfı kapatıyordu; kalan beş sınıfın 18 kusuru bu aşamaya
ulaşır. Dördüncü dersin Y5 politikası da bir durum bırakmıştı: yirmi dokuz sayısal ölçütün
sınırı boştur.

Bu iki miras geri bildirimin sınıfını belirler. Bir kullanıcı bir ölçütü gözlediğinde sonuç
üçe ayrılır: **sınırı boş bir ölçütte** kullanıcı kendi sınırını söyler ve bu bir istektir;
**tam ve altında kusur olan bir ölçütte** bir kusur bildirir; **tam, kusursuz ama ölçüsü
kullanıcıya görünmeyen bir varlık ölçütünde** gördüğünü kendi beklentisiyle karşılaştırır ve
bir yanlış anlama üretir.

**TS18 (varsayım) — 20 iş kalemi 12 kullanıcı görevine dağılır, her göreve en az bir kalem
düşer; kullanım payı tohum 4712'den gelir.**
**TS19 (varsayım) — kabul bütçesi 600 kullanıcı dakikası, bir ölçütü gözlemek 8 dakika**;
bütçe böylece 75 ölçüt gözlemidir ve seksen ölçütün tamamına yetmez.
**TS20 (varsayım) — isteklerin %30'u kabul edilip işe dönüşür**, gerisi kayıtta kalır.
**TS21 (varsayım) — bir isteği karara bağlamak 30, kabul edilen isteği yapmak 120, bir yanlış
anlamayı gidermek 20 dakikadır; kusurun bedeli kusur kümesindeki düzeltme dakikasıdır.**

```js
// kutuphane/kusurlar.mjs — birinci dersin kusur kumesi, aynen (tohum 20260731, 60 kusur,
// 14 sinif). Bu ders envanterin bedel sutunlarini kullanmaz, yalniz kusur kumesini kullanir.
const AGIRLIK = [["kural-siniri", 9], ["sema-uyusmazligi", 6], ["goc-veri-kaybi", 4],
  ["sozlesme-alani", 5], ["arayuz-durumu", 8], ["gorsel-sapma", 3], ["veri-buyumesi", 4],
  ["sql-birlestirme", 3], ["bilinen-acik", 3], ["erisilebilirlik", 4], ["bozulmus-yanit", 3],
  ["kurtarma-eksigi", 2], ["senaryo-disi", 5], ["anlam-sapmasi", 4]];
export function kusurlar(tohum, n) {
  let x = tohum;
  const rast = () => { x = (1103515245 * x + 12345) % 2147483648; return x / 2147483648; };
  const toplam = AGIRLIK.reduce((a, [, w]) => a + w, 0);
  const liste = [];
  for (let i = 1; i <= n; i += 1) {
    let p = rast() * toplam, sinif = AGIRLIK[AGIRLIK.length - 1][0];
    for (const [s, w] of AGIRLIK) { p -= w; if (p < 0) { sinif = s; break; } }
    liste.push({ no: i, sinif, olasilik: 1 + Math.floor(rast() * 5),
      etki: 1 + Math.floor(rast() * 5), duzeltme: 15 + 15 * Math.floor(rast() * 8) });
  }
  return liste;
}
```

## Dört Kapsam Dağıtımı

Aynı 600 dakika dört kurala göre bölünür: eşit (K1), kullanım payına göre (K2), ölçütü en çok
eksik olan göreve (K3) ve yalnız son dört yeni göreve (K4).

```js
// kutuphane/kabul.mjs — kabul kapsamini kullanici gorevlerine dagitir ve donen geri bildirimi
// kusur / istek / yanlis anlama diye ayirir. Girdi: kutuphane/kusurlar.mjs
import { kusurlar } from "./kusurlar.mjs";

const IS = 20, BASINA = 4, GOREV = 12, TOHUM = 20260731, N = 60, KAT = 6;
const BUTCE = 600, OLCUTDK = 8;          // TS19: kabul butcesi, olcut basina kullanici dakikasi
let KABUL = 0.3;                         // TS20: istegin ise donusme orani
const ISTEKDK = 30, YANLISDK = 20, YENIISDK = 120;   // TS21: sinif basina bedel
const v = (x, n = 1) => x.toFixed(n).replace(".", ",");
const g = (x, n) => String(x).padStart(n);
const uret = (t) => { let x = t;
  return () => { x = (1103515245 * x + 12345) % 2147483648; return x / 2147483648; }; };

// Dorduncu dersin olcut kumesi aynen: 80 olcut, tohum 6060, uc tur.
const r = uret(6060);
const TUR = ["varlik", "sayisal", "anlamsal"];
const OLCUTLER = Array.from({ length: IS * BASINA }, (_, i) => { const p = r();
  return { no: i, kalem: Math.floor(i / BASINA), tur: TUR[p < 0.45 ? 0 : p < 0.8 ? 1 : 2] }; });
// Kabul asamasina ulasan kusurlar: ikinci dersin butceye sigan dokuz kaleminin gormedigi
// bes sinif, yani o dersin 18 kacan kusuru. Betikli kumenin gordukleri buraya gelmez.
const ULASAN = new Set(["erisilebilirlik", "bozulmus-yanit", "kurtarma-eksigi",
  "senaryo-disi", "anlam-sapmasi"]);
const KUSUR = kusurlar(TOHUM, N).map((k, i) => ({ ...k, kalem: Math.floor(i / (N / IS)) }))
  .filter((k) => ULASAN.has(k.sinif));
for (const k of KUSUR.filter((k) => k.sinif === "anlam-sapmasi")) {
  const kalemin = OLCUTLER.filter((o) => o.kalem === k.kalem);
  if (kalemin.some((o) => o.tur === "anlamsal") === false)
    Object.assign(kalemin[Math.floor(r() * kalemin.length)], { tur: "anlamsal" });
}
// Dorduncu dersin Y5 politikasinin biraktigi durum: sayisal olcutlerin siniri bostur.
for (const o of OLCUTLER) o.tam = o.tur !== "sayisal";

// TS18: 20 is kalemi 12 kullanici gorevine dagilir (her goreve en az bir kalem);
// gorevin kullanim payi ayni tohumdan gelir.
const r2 = uret(4712);
const PAY = Array.from({ length: GOREV }, () => 1 + Math.floor(r2() * 9));
const PAYTOP = PAY.reduce((a, x) => a + x, 0);
const KALEMGOREV = Array.from({ length: IS }, (_, i) => i % GOREV);
for (let j = IS - 1; j > 0; j -= 1) { const q = Math.floor(r2() * (j + 1));
  [KALEMGOREV[j], KALEMGOREV[q]] = [KALEMGOREV[q], KALEMGOREV[j]]; }
const gorevi = (o) => KALEMGOREV[o.kalem];
// Her kusur kaleminden bir olcutun altinda durur; anlam sapmasi anlamsal olcutte.
const r3 = uret(9313);
for (const k of KUSUR) {
  const aday = OLCUTLER.filter((o) => o.kalem === k.kalem &&
    (k.sinif === "anlam-sapmasi" ? o.tur === "anlamsal" : true));
  k.olcut = aday[Math.floor(r3() * aday.length)];
}
const KUSURLU = new Set(KUSUR.map((k) => k.olcut.no));

// Bir gorevde m dakika: m/OLCUTDK olcut gozlenir. Geri bildirim olcutun durumundan cikar:
// siniri bos olcut -> istek (kullanici kendi sinirini soyler), kusurlu tam olcut -> kusur,
// kusursuz varlik olcutu -> yanlis anlama (olcusu kullaniciya gorunmez, kendi beklentisiyle
// karsilastirir), kusursuz anlamsal olcut -> geri bildirim yok.
function sina(dagitim) {
  const bulgu = { kusur: [], istek: 0, "yanlis anlama": 0 };
  let gozlenen = 0, an = 0, adet = 0;
  for (let go = 0; go < GOREV; go += 1) {
    const liste = OLCUTLER.filter((o) => gorevi(o) === go);
    const kac = Math.min(liste.length, Math.floor(dagitim[go] / OLCUTDK));
    gozlenen += kac;
    liste.slice(0, kac).forEach((o, i) => {
      const t = (i + 1) * OLCUTDK;
      if (o.tam === false) { bulgu.istek += 1; an += t; adet += 1; }
      else if (KUSURLU.has(o.no)) { const l = KUSUR.filter((k) => k.olcut.no === o.no);
        bulgu.kusur.push(...l); an += t * l.length; adet += l.length; }
      else if (o.tur === "varlik") { bulgu["yanlis anlama"] += 1; an += t; adet += 1; }
    });
  }
  const kacan = KUSUR.filter((k) => bulgu.kusur.includes(k) === false);
  // Bulunan kusurun duzeltmesi bir kez, kacanin duzeltmesi TS5 katiyla odenir.
  const o = { gozlenen, an: an / (adet || 1), kusur: bulgu.kusur.length, istek: bulgu.istek,
    yanlis: bulgu["yanlis anlama"], kacan: kacan.length,
    kacanRisk: kacan.reduce((a, k) => a + k.olasilik * k.etki, 0),
    kusurDk: bulgu.kusur.reduce((a, k) => a + k.duzeltme, 0),
    kacanDk: KAT * kacan.reduce((a, k) => a + k.duzeltme, 0),
    istekDk: ISTEKDK * bulgu.istek + KABUL * bulgu.istek * YENIISDK,
    yanlisDk: YANLISDK * bulgu["yanlis anlama"] };
  return { ...o, toplam: o.kusurDk + o.kacanDk + o.istekDk + o.yanlisDk };
}
const esit = () => Array.from({ length: GOREV }, () => BUTCE / GOREV);
const paya = () => PAY.map((p) => (BUTCE * p) / PAYTOP);
const eksige = () => { const e = Array.from({ length: GOREV }, (_, go) =>
  OLCUTLER.filter((o) => gorevi(o) === go && o.tam === false).length);
  const t = e.reduce((a, x) => a + x, 0); return e.map((x) => (BUTCE * x) / t); };
const yeni = () => Array.from({ length: GOREV }, (_, go) => (go >= GOREV - 4 ? BUTCE / 4 : 0));
const D = [["K1 esit dagitim", esit()], ["K2 kullanim payina gore", paya()],
  ["K3 en cok eksik olcute", eksige()], ["K4 yalniz dort yeni goreve", yeni()]];

console.log(`${OLCUTLER.length} olcut (tohum 6060) ${GOREV} kullanici gorevine dagildi (tohum 4712)`);
console.log("gorev basina olcut: " + Array.from({ length: GOREV }, (_, go) =>
  OLCUTLER.filter((o) => gorevi(o) === go).length).join(" ") +
  "; kullanim payi: " + PAY.map((p) => v((100 * p) / PAYTOP, 0) + "%").join(" "));
console.log(`dorduncu dersin Y5 durumu: ${OLCUTLER.filter((o) => o.tam === false).length} olcutun siniri bos; ` +
  `${KUSURLU.size} olcutun altinda kusur var`);

console.log(`\nkabul butcesi TS19 = ${BUTCE} kullanici dk, olcut basina ${OLCUTDK} dk = ${BUTCE / OLCUTDK} olcut`);
console.log("dagitim                   gozlenen  kusur  istek  yanlis anlama  kusur payi  bulgu ani");
for (const [ad, d] of D) { const o = sina(d);
  const t = o.kusur + o.istek + o.yanlis;
  console.log(ad.padEnd(26) + g(o.gozlenen, 8) + g(o.kusur, 7) + g(o.istek, 7) + g(o.yanlis, 15) +
    g(t ? v(o.kusur / t, 2) : "-", 12) + g(v(o.an), 11)); }

console.log("\nsiniflarin bedeli — istek 30 dk karar + %30'u 120 dk is, yanlis anlama 20 dk (TS21)");
console.log("dagitim                   kusur dk   istek dk   yanlis dk   kacan  kacan risk   kacan dk   toplam dk");
for (const [ad, d] of D) { const o = sina(d);
  console.log(ad.padEnd(26) + g(o.kusurDk, 8) + g(v(o.istekDk, 0), 11) + g(o.yanlisDk, 12) +
    g(o.kacan, 7) + g(o.kacanRisk, 12) + g(o.kacanDk, 11) + g(v(o.toplam, 0), 12)); }

console.log("\nTS20'nin duyarliligi: istegin kac katinin ise donustugu");
console.log("kabul orani   " + D.map(([ad]) => g(ad.slice(0, 2), 9)).join("") + "   en ucuz");
for (const p of [0, 0.3, 0.6]) {
  KABUL = p;
  const t = D.map(([, d]) => sina(d).toplam);
  console.log(g("%" + 100 * p, 11) + t.map((n) => g(v(n, 0), 9)).join("") +
    g(D[t.indexOf(Math.min(...t))][0].slice(0, 2), 10));
}
```

```
80 olcut (tohum 6060) 12 kullanici gorevine dagildi (tohum 4712)
gorev basina olcut: 8 8 8 8 8 8 8 8 4 4 4 4; kullanim payi: 4% 8% 10% 12% 3% 10% 10% 3% 12% 12% 12% 6%
dorduncu dersin Y5 durumu: 29 olcutun siniri bos; 15 olcutun altinda kusur var

kabul butcesi TS19 = 600 kullanici dk, olcut basina 8 dk = 75 olcut
dagitim                   gozlenen  kusur  istek  yanlis anlama  kusur payi  bulgu ani
K1 esit dagitim                 64      7     21             30        0,12       25,2
K2 kullanim payina gore         54      8     21             22        0,16       26,0
K3 en cok eksik olcute          60      6     23             24        0,11       28,7
K4 yalniz dort yeni goreve      16      6      4              8        0,33       19,6

siniflarin bedeli — istek 30 dk karar + %30'u 120 dk is, yanlis anlama 20 dk (TS21)
dagitim                   kusur dk   istek dk   yanlis dk   kacan  kacan risk   kacan dk   toplam dk
K1 esit dagitim                675       1386         600     11          88       3510        6171
K2 kullanim payina gore        720       1386         440     10          82       3240        5786
K3 en cok eksik olcute         555       1518         480     12         102       4230        6783
K4 yalniz dort yeni goreve     570        264         160     12          89       4140        5134

TS20'nin duyarliligi: istegin kac katinin ise donustugu
kabul orani          K1       K2       K3       K4   en ucuz
         %0     5415     5030     5955     4990        K4
        %30     6171     5786     6783     5134        K4
        %60     6927     6542     7611     5278        K4
```

## Geri Bildirim Hacmi Bir Kalite Ölçüsü Değildir

Dört dağıtımın ürettiği geri bildirimin **kusur payı** 0,11 ile 0,33 arasındadır. Yani en iyi
durumda üç bildirimden biri, en kötü durumda dokuz bildirimden biri gerçek bir kusurdur;
gerisi istek ve yanlış anlamadır. K1 elli sekiz bildirim üretir ve bunun yalnız yedisi
kusurdur. Bir kabul turunu "elli sekiz bulgu" diye özetlemek, ekibe yedi kusurdan söz ettiğini
söylemez.

Sınıflandırma yapılmadan bu ayrım görünmez: üç sınıf aynı listeye düşer ve aynı biçimde
yazılır. Ayrımı ölçüte bağlamak onu bir yargı olmaktan çıkarır: sınırı boş bir ölçütte gelen
bildirim istektir, çünkü ortada karşılanmayan bir söz yoktur — kullanıcının sınırı ilk kez
orada söylenmektedir.

## Hangi Dağıtım Ne Satın Alır

K3 en çok isteği getiren dağıtımdır (23). Şaşırtıcı değildir: eksik ölçütü hedeflemek, tanımı
gereği sınırı yazılmamış ölçütleri gözletir. Kaçan hatası da en
yüksektir (12) ve toplamı en pahalıdır (6.783 dakika). **Belirsizliği hedeflemek kusuru değil
isteği bulur.**

K2 kullanım payına göre dağıtır, en çok kusuru bulur (8) ve en az kusuru kaçırır (10, kaçan
risk 82). Kullanıcının çok kullandığı görevde duran kusur, sınandığında bulunur. Buna karşılık
K2 gözleyebildiği ölçüt sayısında en düşüktür (54), çünkü bütçenin büyük parçası az sayıda
göreve gider.

K4 en ucuz görünür (5.134 dakika) ve en yüksek kusur payına sahiptir (0,33). Nedeni bir
üstünlük değildir: yalnız on altı ölçüt gözlediği için gürültü de üretmez. İstek ve yanlış
anlama bedeli 424 dakikada kalır, ama on iki kusuru kaçırır. **Toplam bedel sütunu tek başına
yanıltıcıdır, çünkü geri bildirim üretmemek ucuzdur.** İki sütunu birlikte okumak gerekir:
K2 kaçan hatada, K4 işlenen bildirimde ucuzdur ve ikisi aynı şeyi ölçmez.

TS20 taraması bunu doğrular. İsteklerin hiçbiri işe dönüşmese bile (kabul oranı %0) sıralama
değişmez; %60'a çıkarıldığında K4'ün önü açılır, çünkü işlenecek isteği zaten azdır. Bir kabul
turunun bedelini asıl belirleyen, bulunan kusur sayısı değil **işlenen bildirim sayısıdır.**

## Kararın Geri Dönüşü

Kabul testinin kırmızısı tek bir karar değildir, üç ayrı kuyruktur. Kusur sürümü durdurur ve
düzeltmeye gider. İstek ürün tarafının kararına gider ve %30'u işe dönüşür; kalanı bir kayıt
olarak durur. Yanlış anlama koda değil arayüz metnine ya da belgeye gider ve dördüncü dersin
ölçüt yuvalarına geri besleme yapar — bir yanlış anlama, ölçüsü kullanıcıya görünmeyen bir
ölçütün işaretidir.

Bulgunun ortalama anı 19,6 ile 28,7 dakika arasındadır, ama bu sayı yanıltıcı biçimde küçüktür:
kabul penceresi geliştirme bittikten **sonra** açılır. İkinci dersin betikli kümesi kusuru
ortalama 18,2 dakikada, üçüncü dersin keşifsel oturumu 74,8 dakikada haber veriyordu; kabul
testinin bulgusu ise ancak 600 dakikalık pencere açıldığında ortaya çıkar. Aynı kusur zinciri
boyunca haber verme anı büyür ve bedeli onunla büyür.

## Özet

- Kabul aşamasına yalnız önceki kapıların görmediği kusurlar ulaşır: ikinci dersin beş kapalı
  olmayan sınıfından 18 kusur.
- Geri bildirim üç sınıftır ve sınıfı ölçütün durumu belirler: sınırı boş ölçüt istek, kusurlu
  tam ölçüt kusur, ölçüsü kullanıcıya görünmeyen kusursuz ölçüt yanlış anlama üretir.
- Kusur payı 0,11 ile 0,33 arasındadır; bir kabul turunu bulgu sayısıyla özetlemek ekibe kaç
  kusur bulunduğunu söylemez.
- Belirsizliği hedefleyen dağıtım en çok isteği ve en çok kaçan hatayı üretir (23 istek, 12
  kaçan, 6.783 dakika); kullanım payına göre dağıtım en çok kusuru bulur (8) ve en az kaçırır.
- En düşük toplam bedelli dağıtım en az bildirim üretendir (K4, 5.134 dakika, 12 kaçan); geri
  bildirim üretmemek ucuzdur, bu yüzden toplam bedel tek başına okunmaz.
- Kabul testinin kırmızısı üç ayrı kuyruğa gider: düzeltme, ürün kararı ve arayüz metni;
  yanlış anlama ölçüt yuvalarına geri besleme yapar.

## Sonraki Adım

Bu konu dört karar bıraktı. Plan kapsamı, ölçütü ve sorumluluğu yazdı; risk sırası aynı
bütçeyi olasılık ile etkiye göre böldü; keşifsel oturum betikli kümenin göremediği sınıfa
genişlik yerine derinlikle ulaştı; kabul ölçütü ve kullanıcı kabul testi tamamlanmanın tanımını
ekibin dışına taşıdı. Dördünün ortak yanı şudur: hepsi **kâğıt üzerinde** bir dağıtımdır. Bir
plan yazılıdır ama koşmaz; bir risk sırası bir listedir ama kimse ona bakmadan da değişiklik
gönderebilir; bir oturum kapsamı ancak biri oturmaya karar verirse açılır; bir kabul ölçütü
ancak biri onu okursa kapanır. Bu dağıtımın her değişiklikte, kimsenin hatırlamasına
kalmadan, kendiliğinden işlemesi için bir düzenek gerekir — ve o düzenek hiç kurulmadı.
Otomasyon Altyapısı konusu tam buradan başlar.
