---
title: 'Parametreli Testler'
source: 'https://academia.sh/tr/kurslar/java-ekosistem/parametreli-testler'
course: 'Derleme, Test ve Ekosistem'
language: tr
updated: '2026-08-23T14:25:06+00:00'
license: 'CC BY-SA 4.0'
---

# Parametreli Testler

Tek bir gövde, bildirilen bir veri kümesi üzerinde üç kez çağrılıyor ve her çağrı kendi satırının başarılı ya da düştüğünü kaydediyor. Kurulum döngünün dışına taşınıp bir Depo örneği satırlar arasında paylaşıldığında ise hangi satırın geçtiği veri kümesinin sırasına bağlı hâle geliyor, aynı üç satır ters sırayla farklı bir satırı geçirtiyor.

Önceki derste tek bir test gövdesi üç ayrı sınıf yoluna karşı koşturuldu, ama her koşumda
aynı üç sayı kullanıldı. Bu derste gövde sabit kalıyor, değişen taraf veri: aynı kontrolü
üç ayrı girdiyle çalıştırmak için gövdeyi üç kez yazmak yerine, veri kümesini bir bildirim
olarak yazıp gövdeyi **bir kez** kuruyoruz. Soru şu: bir gövde, N satırlık bir veri kümesine
karşı çağrıldığında kaç ayrı sonuç üretiyor, kaçı düşüyor, ve düşen satır hangisi olduğunu
nereden biliyoruz?

Bu sorunun ikinci yarısı ilk bakışta ayrı görünüyor ama değil: aynı gövdeyi N kez çalıştırmak,
N koşumun birbirinden bağımsız olduğunu **varsayar**. Gövde bir kez yazıldığı için, bir
satırın kurulumu bir sonraki satırın kurulumuyla aynı koddan geçer — ve o kodun paylaşılan
bir değişkene dokunup dokunmadığı, veri kümesinin kendisinde hiç görünmez. Bu ders önce
doğru kurulmuş bir gövdeyle üç bağımsız sonucu sayıyor, sonra aynı veriyi bozuk bir kurulumla
koşturup varsayımın ne zaman çöktüğünü gösteriyor.

Veri kümesinin kendisi burada üç satırla sınırlı tutuluyor, ama sayının kendisi önemli
değil — önemli olan, N ne olursa olsun aynı gövdenin N kez çağrılabilmesi ve her çağrının
kendi sonucunu üretebilmesidir. Üç satır, elle izlenebilecek en küçük sayı olduğu için
seçildi; aynı kurulum hatası yüz satırlık bir veri kümesinde de aynı biçimde ortaya çıkar,
yalnız izlemesi güçleşir.

## Veri Kümesi Bildirimde Durur, Gövde Bir Kez Yazılır

- **TS11.** Veri kümesi burada bir `record` dizisi olarak bildirilir (`Veri[]`). Gerçek
  çerçevelerin veri kaynağını bir dosyadan, bir ek açıklamadan ya da bir yöntem
  referansından okuma mekanizması burada kurulmaz — veri doğrudan kaynak kodda durur.
- **TS12.** Gövde burada veri dizisinde gezinen bir döngüdür; aynı üç satır aynı sırayla,
  her biri kendi girdisiyle bir kez çağrılır. Çağrı sayısı veri satırı sayısına eşittir.

Aşağıdaki `VERI` dizisi üç satır taşıyor; her satır bir başlangıç miktarı, bir azaltma ve
beklenen sonucu bir arada tutuyor. `bagimsizKosum` gövdesi bu üç satırı sırayla işliyor ve
her satır için **kendi** `Depo` örneğini kuruyor — kurulum satırın içinde, döngünün her
turunda yeniden çalışıyor. Aşağıda aynı veri kümesi, kurulumun döngü **dışına** taşındığı
bozuk bir sürümle de koşturuluyor; ikisi arasındaki fark bu dersin asıl konusu.

```java
// Veriler.java — tek govde, veri kumesince cogaltilan kosum, ve paylasilan durumun sirali bagimliligi
import java.util.*;

public class Veriler {

    static class Depo {
        private int miktar;
        Depo(int baslangic) { miktar = baslangic; }
        void azalt(int adet) { miktar -= adet; }
        int miktar() { return miktar; }
    }

    record Veri(int baslangic, int azalt, int beklenen) {}

    static final Veri[] VERI = {
        new Veri(10, 3, 7),
        new Veri(5, 2, 3),
        new Veri(8, 8, 0),
    };

    // -- govde bir kez yazilir, N koşumun her biri kendi Depo'sunu kurar --------------------
    static List<String> bagimsizKosum(Veri[] veri) {
        List<String> gunluk = new ArrayList<>();
        int dusen = 0;
        for (int i = 0; i < veri.length; i++) {
            Veri v = veri[i];
            Depo d = new Depo(v.baslangic());
            d.azalt(v.azalt());
            boolean gecti = d.miktar() == v.beklenen();
            if (!gecti) dusen++;
            gunluk.add("satir " + i + ": " + (gecti ? "gecti" : "dustu, gelen=" + d.miktar()));
        }
        gunluk.add("dusen sayisi: " + dusen);
        return gunluk;
    }

    // -- kurulum yanlislikla dongunun disina alinirsa Depo koşumlar arasinda paylasilir -----
    static List<String> paylasilanKosum(Veri[] veri) {
        List<String> gunluk = new ArrayList<>();
        int dusen = 0;
        Depo d = new Depo(veri[0].baslangic());
        for (int i = 0; i < veri.length; i++) {
            Veri v = veri[i];
            d.azalt(v.azalt());
            boolean gecti = d.miktar() == v.beklenen();
            if (!gecti) dusen++;
            gunluk.add("satir " + i + ": " + (gecti ? "gecti" : "dustu, gelen=" + d.miktar()));
        }
        gunluk.add("dusen sayisi: " + dusen);
        return gunluk;
    }

    public static void main(String[] args) {
        System.out.println("-- bagimsiz kosum: her satir kendi Depo'sunu kuruyor --");
        bagimsizKosum(VERI).forEach(System.out::println);

        System.out.println("-- paylasilan kosum, veri sirasi orijinal --");
        paylasilanKosum(VERI).forEach(System.out::println);

        Veri[] tersVeri = { VERI[2], VERI[1], VERI[0] };
        System.out.println("-- paylasilan kosum, ayni veri, sira tersine cevrildi --");
        paylasilanKosum(tersVeri).forEach(System.out::println);
    }
}
```

```
-- bagimsiz kosum: her satir kendi Depo'sunu kuruyor --
satir 0: gecti
satir 1: gecti
satir 2: gecti
dusen sayisi: 0
-- paylasilan kosum, veri sirasi orijinal --
satir 0: gecti
satir 1: dustu, gelen=5
satir 2: dustu, gelen=-3
dusen sayisi: 2
-- paylasilan kosum, ayni veri, sira tersine cevrildi --
satir 0: gecti
satir 1: dustu, gelen=-2
satir 2: dustu, gelen=-5
dusen sayisi: 2
```

`bagimsizKosum` üç satırın üçünü de geçiriyor. Bu beklenen sonuç, çünkü her satır kendi
`Depo`'sunu sıfırdan kuruyor — üçü de birbirinden habersiz, birbirinin durumuna dokunmuyor.
Gövde tek bir yerde yazıldı (döngünün gövdesi), ama üç kez çalıştı ve üç ayrı sonuç üretti.
Başarısızlık sayısı (`dusen sayisi`) ve her satırın kendi durumu (`satir i: gecti`/`dustu`)
ayrı ayrı günlüğe geçiyor — bir satır düştüğünde hangi satır olduğu ve dönen değer kayıtta
kalıyor, yalnız toplam bir sayı değil.

Bu, önceki dersteki "bir iddia" fikrinden farklı bir sayma biçimi. Orada bir test bir sonuç
üretiyordu; burada bir gövde N kez çağrılıyor ve N ayrı iddia doğuruyor. Üç satırlık bir veri
kümesi üç ayrı iddia demektir, ve üçünün de bağımsız değerlendirilmesi gerekir — biri
düşerken diğer ikisinin geçmesi hâlâ anlamlı bir sonuçtur, çünkü her satır kendi girdisini
kendi başına sınıyor. Gövdenin bir kez yazılması burada bir kısaltmadır, kaynak metindeki
tekrarı azaltır; ama derlenmiş ya da koşan programda üç ayrı çağrı olduğu gerçeğini
değiştirmez. `VERI` dizisi ve `bagimsizKosum`/`paylasilanKosum` yöntemleri de önceki dersin
kurduğu ayrımın dışında değil — bunların hiçbiri üretim kodunda yazılı değil, ikisi de
yalnız test sınıf yolunda durur.

## Paylaşılan Kurulum, Sıraya Bağlı Sonuç

- **TS13.** Başarısızlığın hangi satırdan geldiği burada bir liste elemanı olarak
  biriktirilir. Gerçek çerçevelerin ürettiği rapor biçimi (dosya adı, satır numarası,
  yığıt izi) burada kurulmaz; kayıt yalnız satır indeksi ve gelen değerdir.
- **TS14.** Paylaşılan durum burada döngünün dışına taşınan tek bir `Depo` örneğidir.
  Kurulumun döngünün neresinde çalıştığı — her turda mı, bir kez mi — satırların
  birbirinden bağımsız olup olmadığını belirler.
- **TS15.** Sıra bağımlılığı burada aynı veri kümesinin ters çevrilmiş bir kopyasıyla
  gösterilir. Gerçek bir test takımında satırların (ya da testlerin) çalışma sırası
  çoğunlukla belgelenmez ve koşumdan koşuma değişebilir; bu ders yalnız iki olası sırayı
  örnekliyor.

`paylasilanKosum` aynı üç satırı, aynı iddiayı taşıyor — tek fark, `Depo`'nun döngünün
**dışında**, yalnız bir kez kurulmasıdır. Bu, kurulumun her satır için yeniden çalışması
gerekirken yanlışlıkla yalnız ilk satır için çalıştığı bir hatayı modelliyor: `d` nesnesi
ilk satırın başlangıç değerinden kuruluyor, sonra her satırın `azalt` çağrısı **aynı**
nesne üzerinde birikiyor. Orijinal sırada ilk satır geçiyor — çünkü paylaşılan `Depo` tam
o satırın beklediği başlangıç değeriyle kuruldu — ama ikinci ve üçüncü satır artık kendi
beklediği başlangıç durumunu görmüyor, önceki satırların bıraktığı durumu görüyor ve
ikisi de düşüyor.

Sayıları takip etmek farkı netleştiriyor. Paylaşılan `Depo`, `VERI[0].baslangic()` olan
10 ile kuruluyor. Birinci satır `azalt(3)` çağırıyor, miktar 7 oluyor, beklenen de 7 —
geçiyor. İkinci satır kendi başlangıcı olan 5'i hiç görmüyor; onun yerine birincinin
bıraktığı 7'yi görüyor ve `azalt(2)` çağırınca miktar 5 oluyor, beklenen 3 olduğu için
düşüyor. Üçüncü satır da kendi başlangıcı olan 8'i değil, ikincinin bıraktığı 5'i görüyor;
`azalt(8)` çağırınca miktar -3'e düşüyor, beklenen 0'dan uzak. Her satırın kendi verisi
doğru, kendi hesabı doğru — yanlış olan, hangi durumdan başladıklarıdır.

Asıl gösterim son iki koşumda. Aynı üç veri satırı, yalnız sırası tersine çevrilerek
tekrar koşturuluyor. Sonuç yine "bir satır geçti, ikisi düştü" biçiminde — ama geçen satır
**değişti**. Orijinal sırada geçen satır, verinin ilk satırıydı (10 → 7); tersine çevrilmiş
sırada geçen satır, o sırada ilk gelen satırdır (8 → 0). Veri kümesinin kendisi değişmedi,
satırların hiçbirinin içeriği düzenlenmedi — yalnız hangi satırın **önce** işlendiği
değişti, ve bu tek değişiklik hangi satırın geçtiğini baştan aşağı değiştirdi. Bir satırın
geçip geçmemesi artık o satırın kendi verisine değil, konumuna bağlı.

Tersine çevrilmiş sırada aynı izleme yapılabilir. Paylaşılan `Depo` bu kez `8` ile kuruluyor
— tersine çevrilmiş dizinin ilk elemanı olan üçüncü satırın başlangıcı. O satır `azalt(8)`
çağırıyor, miktar `0` oluyor, beklenen de `0` — geçiyor. Sırada ikinci satır olarak gelen
ikinci veri satırı kendi başlangıcı olan 5'i değil, önceki adımın bıraktığı 0'ı görüyor;
`azalt(2)` çağırınca miktar -2 oluyor, beklenen 3'ten uzak, düşüyor. Son olarak gelen
birinci veri satırı kendi başlangıcı olan 10'u değil, -2'yi görüyor; `azalt(3)` çağırınca
miktar -5 oluyor, beklenen 7'den uzak, düşüyor. İki koşumda da yalnızca **ilk işlenen**
satır geçiyor — çünkü paylaşılan `Depo` yalnız o satırın beklediği başlangıç değeriyle
kuruluyor — ve geriye kalanlar önceki satırların bıraktığı durumu devralıp düşüyor. Hangi
satırın "ilk işlenen" olduğu ise veri dizisinin sırasına bağlı, satırın kendi içeriğine
değil.

Bu, M21/K02 Birim Testi ve Test Odaklı Geliştirme kursunda kurulan kararsız test kavramının
somut bir kaynağıdır: testler arasında (ya da burada olduğu gibi, aynı testin satırları
arasında) paylaşılan durum, sonucu çalışma sırasına bağlı kılar. Kavramın kendisi orada
kuruldu; bu derste yeni olan, kaynağın **nerede** durduğudur — kurulumun döngü içinde mi
dışında mı çalıştığı, bildirilen veri kümesinin kendisinde görünmeyen bir karardır. İki
koşumun günlüğüne bakarak bu kararı geri çıkarmak mümkün değildir; yalnız veri sırası
değiştirilip yeniden koşturularak görünür hâle gelir.

Bu yüzden gerçek test çerçevelerinin çoğu, satırların ya da testlerin çalışma sırasını
**bilinçli olarak** karıştırır: iki ayrı koşumun her seferinde aynı sırayı vermesi,
paylaşılan durumdan doğan bir hatayı gizli tutar. Sıra her koşumda sabit kalırsa, bu ders
göstermiş olduğu ikinci koşumdaki gibi bir sapma hiç ortaya çıkmayabilir — takım "geçti"
der, ama yalnız çünkü sıra hep aynıdır. Sıra karıştırıldığında ise aynı hatalı kurulum
bazen bir satırı, bazen başka bir satırı geçirir ve toplam başarısızlık sayısı koşumdan
koşuma değişir görünebilir. Bu değişkenlik, hatanın belirtisidir — testin kendisinde değil,
testler arasında paylaşılan bir durumda aranması gerektiğinin işaretidir.

Buradan çıkan kural şudur: parametreleme bir gövdeyi çoğaltır, ama çoğalan koşumların
birbirinden **bağımsız** olduğunu garanti etmez. Bağımsızlığı garanti eden şey, her koşumun
kendi kurulumunu kendi başına çalıştırmasıdır — `bagimsizKosum`'da olduğu gibi. Kurulum bir
kez çalışıp N koşum arasında paylaşıldığında, veri kümesi ne kadar doğru yazılmış olursa
olsun, sonuç veri kümesinin **sırasına** bağlı hâle gelir. Bir satırın geçmesi artık o
satırın doğru olduğunu değil, o satırın konumunun uygun düştüğünü gösterir.

Hatanın kökeni bir aliaslama sorunudur: iki ayrı satırın iki ayrı `Depo` beklediği yerde,
tek bir `Depo` referansı ikisi arasında paylaşılıyor. Kaynak metinde bu paylaşım açıkça
görünmüyor — `d` adı döngünün her turunda aynı satırda geçiyor, değişen yalnız hangi
`Veri` kaydının işlendiği. Değişkenin **kapsamı** (döngünün dışı) ile **niyet edilen ömrü**
(tek bir satır) burada birbirinden ayrılıyor, ve bu ayrılığı kaynak metinden görmek
mümkün değil; yalnız birden çok satırla, birden çok sırayla koşturarak görülüyor. Bu
gözlem, kursun ölçü sorusunu test verisi düzeyine indiriyor: bir kurulumun "hangi kapsamda"
çalıştığı da, tıpkı bir tipin hangi sınıf yolunda durduğu gibi, kaynak metinde açıkça
yazılmayan ama sonucu belirleyen bir karardır.

Kurulumu döngü dışına almanın bir bedeli olmadığını düşünmek de yanıltıcı olurdu — tam
tersi, o taşımanın kendisi genellikle bir kazanç aramanın sonucudur. `bagimsizKosum` her
satır için yeni bir `Depo` kuruyor; bu, N satırlık bir veri kümesinde N ayrı kurulum çağrısı
demektir. Kurulum ağır bir işse — gerçek bir bağlantı açmak, büyük bir yapı kurmak — bu
tekrar maliyetli görünebilir ve kurulumu bir kez yapıp paylaşmak cazip gelir. Bu ders o
cazibenin bedelini gösteriyor: paylaşılan kurulumun kazandırdığı hız, satırlar arasındaki
bağımsızlığı kaybettirdiği için ödenmiş oluyor. İki özelliği aynı anda istemek — hem
paylaşılan hem bağımsız bir kurulum — çelişkilidir; hangisinin öncelikli olduğu, gövdeyi
yazan kişinin kararındadır ve bu ders yalnız o kararın sonucunu ölçüyor.

Bu seçimin doğru yanıtı yoktur, yalnız bilinçli ve bilinçsiz biçimleri vardır. Bir gövde
kurulumu bilinçli olarak paylaşıyorsa — örneğin satırların ortak, değişmeyen bir kaynağı
okuduğu, hiçbirinin yazmadığı durumlarda — paylaşım bir kusur değildir. Kusur, paylaşımın
**yazma** içeren bir kurulumda, farkında olunmadan gerçekleşmesindedir. Bu dersin
`paylasilanKosum` yöntemi ikinci durumu modelliyor: kurulum döngü dışına taşınırken hangi
satırın hangi durumu göreceği hiç düşünülmemiş, yalnız tekrarı azaltmak hedeflenmiştir.

## Özet

- Veri kümesi bir bildirim olarak yazıldı, gövde bir kez kuruldu ve veri sayısınca — üç
  kez — çağrıldı; her çağrı kendi satırının sonucunu kaydetti.
- Bağımsız kurulumla üç satırın üçü de geçti; başarısızlık sayısı ve hangi satırdan
  geldiği ayrı ayrı günlüğe geçti.
- Kurulum döngünün dışına taşınıp tek bir `Depo` satırlar arasında paylaşıldığında iki
  satır düştü, ama hangi satırın geçtiği veri sırasına bağlı hâle geldi.
- Aynı üç satır ters sırayla koşturulduğunda geçen satır değişti; veri içeriği aynı kaldı,
  yalnız işlenme sırası değişti.
- Paylaşılan durumun sonucu sıraya bağlı kılması, M21/K02'de kurulan kararsız test
  kavramının bu derste somutlaşan bir kaynağıdır.

## Sonraki Adım

Bu derste paylaşılan olan şey bir test gövdesinin kendi kurduğu bir nesneydi — sınanan
kodun dışına, testin kendi düzenine ait bir hataydı. Sınanan kodun kendisi (`Depo`) hiç
değişmedi; değişen yalnız test tarafının kurulumuydu. Sıradaki ders paylaşılan durumu
sınanan kodun **dışına** taşıyor: birim testinde sahtelenen bir bağımlılık, tümleşim
kurulumunda gerçek gerçekleştirimiyle yerine konuyor ve aynı test gövdesi artık daha büyük
bir sınıf yoluna karşı koşuyor. Kusurun nereye taşındığı — birimde sessiz kalan bir sapma,
tümleşimde nasıl bir hataya dönüşüyor — sıradaki dersin sorusu.
