---
title: 'Belge Testleri'
source: 'https://academia.sh/tr/kurslar/python-projeleri/belge-testleri'
course: 'Python Projeleri: Paketleme ve Test'
language: tr
updated: '2026-08-17T18:10:31+00:00'
license: 'CC BY-SA 4.0'
---

# Belge Testleri

On iki belge iddiasının yedisi bir biçim değişikliğiyle bayatlar; düzyazı ağırlıklı yazımda bunların 4'ü sese döner ve 3'ü sessiz kalır, iki iddia örneğe çevrildiğinde sesli sayı 6'ya çıkar ve geriye yalnız gerekçe kalır — aynı bayatlama, 2 ayrı sonuç.

Önceki ders sahte nesnenin ayrı sonuç sayısını üçten bire indirdiğini, ama gerçek kaynakla
uyum hakkında hiçbir şey söylemediğini ölçtü. Oradaki iddialar — beklenen sürüm kümesi,
beklenen çağrı sayısı — bir test dosyasında yazılıydı ve her koşumda çalışıyordu. Yanlış
olabilirlerdi, ama sessiz kalamazlardı.

Bir projenin doğruluk iddiaları yalnız test dosyalarında durmaz. Bir işlevin belge
dizgisinde yazan "bu çağrı şu değeri döndürür" cümlesi de bir iddiadır. Aradaki fark
şudur: **o cümleyi hiçbir koşum sınamaz.** Kod değiştiğinde cümle olduğu yerde kalır,
hiçbir şey kırılmaz ve iddia sessizce yanlışlanır. Bu dersin sorusu şudur: **aynı belge,
aynı değişiklikten sonra kaç bayat iddiayı sese çevirir?**

## Sessiz Bayatlama ve Sesli Bayatlama

Bir doküman iddiasının bağlandığı yüzey değiştiğinde iddia **bayatlar (staleness)**.
Yazılım Geliştirme Pratiği müfredatının Teknik Yazarlık ve Dokümantasyon kursu bunu elli
altı iddia üzerinden ölçmüş ve iki sınıfa ayırmıştı: çalıştırılabilir örneğe gömülü bir
iddia bayatlayınca **ses çıkarır** — örnek çalışmaz; gömülü olmayan bir iddia bayatlayınca
hiçbir şey olmaz, bu **sessiz bayatlamadır**. O ölçümde elli altı iddianın on yedisi
gömülüydü ve bu sayı bir veriydi, bir seçim değil.

**Bu derste gömülülük bir seçimdir.** Ölçüm oradaki sayıları tekrarlamaz; sorduğu soru
farklıdır: aynı iddia düzyazı olarak da, çalıştırılabilir örnek olarak da yazılabiliyorsa,
yazımı değiştirmek sese dönen bayat iddia sayısını ne yapar? Yani orada gömülülük ölçümün
**girdisiydi**, burada ölçümün **değişkenidir**.

Bunu ölçülebilir kılan düzeneğe **belge testi (doctest)** denir ve standart kitaplığın
`doctest` modülü tarafından sağlanır. Düzenek basittir: belge metnindeki etkileşimli kabuk
istemiyle başlayan satırlar birer ifade, altlarındaki satırlar da beklenen çıktı sayılır.
Modül ifadeleri çalıştırır, çıktıyı beklenenle karşılaştırır ve uyuşmayanları düşen örnek
olarak sayar. Yani belge, kendisi bir test takımı haline gelir.

Belge testinin bir birim test takımının yerini almadığını baştan yazmak gerekiyor. Sınadığı
şey belgede yazan örnektir; belgede yazmayan bir sınır durumu, bir hata yolu ya da bir
başarısızlık senaryosu belge testine hiç girmez. Örnekleri kapsayıcı olsun diye çoğaltmak
da belgeyi okunmaz hale getirir — belge okunmak için yazılır, sınamak için değil. Belge
testinin işi bu yüzden kapsamı büyütmek değil, **zaten yazılmış olan iddiaları ayakta
tutmaktır.**

## İddianın İki Yazımı

Aynı bilgi iki türlü yazılabilir. "Sürüm metni noktayla ayrılmış sayılardan oluşur" bir
düzyazı iddiadır; okunur, anlaşılır ve hiçbir şey tarafından sınanmaz. Aynı bilgi bir
çağrı ile beklenen çıktısı olarak yazıldığında ise sınanabilir hale gelir — ve okunurluğu
da genellikle artar, çünkü örnek soyut bir tarifin yerine somut bir değer koyar.

İkisi arasındaki seçim bir üslup tercihi gibi görünür, oysa ölçülebilir bir farkı vardır.
Düzyazı iddia bayatladığında bunu ancak bir insan okuyup fark eder; örnek bayatladığında
koşum kırmızı olur. Ölçüm bu farkı tam olarak sayıyor.

## Belge Testi Neyin Yazılabileceğini Sınırlar

Belge testinin karşılaştırma kuralı katıdır: beklenen çıktı ile gerçekleşen çıktının
**metin olarak** eşit olması gerekir. Bu kural, belgeye hangi örneğin konabileceğini de
belirler — çıktısı her koşumda aynı olmayan bir örnek belgeye konamaz.

Python'da bu kısıtın birkaç bilinen kaynağı vardır. Bir nesnenin varsayılan gösterimi
kimliğine bağlı bir sayı taşır ve o sayı koşumdan koşuma değişir; kayan noktalı bir sayının
gösterimi işlemin sırasına duyarlıdır; bir kümenin ya da sözlük anahtarlarının yazdırılma
düzeni, üzerinde durulması gereken ayrı bir konudur. Bu yüzden belge örnekleri ya
**belirlenimci** bir değer döndürecek biçimde yazılır, ya da çıktı sıralanarak,
biçimlendirilerek ya da bir karşılaştırmaya indirgenerek belirlenimci hale getirilir.

Ölçümdeki örnekler bunu doğrudan gösteriyor. Fark işlevinin sonucu `sorted` ile
sıralanmış bir listedir; sıralama olmasaydı örnek koşumdan koşuma başka bir düzen
verebilirdi. Kilit metnini üreten işlev de paketleri ad sırasına göre yazar. İkisi de
belgeyi sınanabilir kılmak için değil, sonucu okunur kılmak için yapılmış tasarım
kararlarıdır — ama belge testi bu kararların üzerine oturur.

Buradan çıkan sonuç ilk bakışta ters görünür: **belge testini eklemek, belgeyi değil kodu
etkiler.** Bir işlevin çıktısı belirlenimci değilse, o işlevin belgesi sınanabilir hale
gelemez; getirilmek isteniyorsa değişmesi gereken şey işlevin kendisidir.

## Örneğe Çevrilemeyen İddia

Her düzyazı iddia örneğe çevrilemez ve bu, belge testinin sınırıdır. Belge testi bir
ifadenin **değerini** karşılaştırır; değeri olmayan bir cümleyi karşılaştıramaz.

Ölçümdeki altı düzyazı iddiadan beşi bir çağrının sonucuna bağlıdır ve örneğe çevrilebilir.
Altıncısı bir **gerekçedir**: "önek yazılmaz, çünkü metin sayı gibi sıralanır." Bu cümlenin
sınanabilir yarısı — önek yazılmaması — zaten başka bir örnekte sınanıyor; sınanamayan
yarısı ise cümlenin asıl taşıdığı bilgidir, yani kararın nedeni. Bir nedenin döndürdüğü
değer yoktur.

Bu ayrım pratikte şuna karşılık gelir: belge testi **ne olduğunu** yazan cümleleri
koruyabilir, **neden öyle olduğunu** yazan cümleleri koruyamaz. İkinci sınıf, bayatladığında
en pahalı olan sınıftır, çünkü yanlış bir gerekçe okuyan kişiyi yanlış bir kararla baş
başa bırakır. Bir örnek düştüğünde okuyan kişi belgeye güvenmeyi bırakır; bir gerekçe
bayatladığında ise okuyan kişi belgeye güvenmeye devam eder ve yanlış tarafa yönelir.

## Ölçümün Varsayımları

- **PT29** — Belgelenen dört işlev bu dersin kendi işlevleridir: sürüm metni, kilit metni
  ve iki sözlük arasındaki farkı veren işlev. Ortak tanımın `DEPO`, `BILDIRIM` ve
  `indirim` tanımlarına dokunulmaz.
- **PT30** — İddia toplamı **12**'dir. Altısı belge metnindeki çalıştırılabilir örnek,
  altısı düzyazı cümledir. İki yazımda da toplam aynıdır; değişen yalnız dağılımdır.
- **PT31** — Değişiklik bir biçim değişikliğidir: sürüm metnine bir önek eklenir ve kilit
  metninin alan ayracı değişir. Fark işlevi dokunulmadan kalır.
- **PT32** — Kâhin kurgunun kendisidir: her iki gerçekleştirimi de biz yazdığımız için
  hangi iddianın bayatladığını biliyoruz. Düzyazı iddiaların bayatlığı bu bilgiden
  işaretlenir.
- **PT33** — Çalıştırılabilir örneklerin bayatlığı işaretlenmez, **ölçülür**: belge
  testi koşturulur ve düşen örnek sayısı okunur.
- **PT34** — İkinci yazımda, örneğe çevrilebilen **bayat** düzyazı iddialar örneğe
  çevrilir. Bayat olmayanlar düzyazı kalır; ölçüm yalnız bayatlamanın sesini sayar.
- **PT35** — Örneğe çevrilemeyen tek iddia gerekçedir ve her iki yazımda da düzyazı kalır.
- **PT36** — Belge testi belge metnini kaynaktan ayrı bir dizgi olarak alır ve iki ayrı
  gerçekleştirim kümesiyle koşturulur; koşum çıktısı yutulur, yalnız sayılar okunur.
- **PT37** — Bir örnek, beklenen çıktısı gerçekleşen çıktıya eşit değilse düşer; kısmi
  eşleşme yoktur.
- **PT38** — Değişiklikten önce her iki yazım da **0** başarısızlık verir; belge yazıldığı
  gerçekleştirimle uyumludur.
- **PT39** — Süre ölçülmez, depoya dosya bırakılmaz. Sayılan şey iddia, bayat iddia, düşen
  örnek ve sessiz kalan iddia sayısıdır.
- **PT40** — Ayrı sonuç sayısı, iki belge yazımının verdiği **sese dönen bayat iddia**
  sayılarının birbirinden farklı olanlarının sayısıdır.

## Ölçüm

```python
"""Belge testi: ayni belge iki yazimda, ayni bayatlama iki ayri sonuc.

Bolum 1 - belgedeki ornekler kosturulur; duzyazi iddialar kahinden isaretlenir.
Bolum 2 - iki duzyazi iddia ornege cevrilir ve olcum yinelenir.
"""
import doctest

SECIM = {"olcum": (1, 2), "ortak": (3, 2), "rapor": (1, 1)}
ONCEKI = {"olcum": (1, 1), "ortak": (3, 2), "rapor": (1, 1)}


def eski_surum(s):
    return ".".join(map(str, s))


def yeni_surum(s):
    return "v" + ".".join(map(str, s))


def eski_kilit(secim):
    return " ".join(f"{p}={eski_surum(secim[p])}" for p in sorted(secim))


def yeni_kilit(secim):
    return ", ".join(f"{p}={yeni_surum(secim[p])}" for p in sorted(secim))


def fark(a, b):
    return sorted(p for p in a if a[p] != b[p])


ESKI = {"surum": eski_surum, "kilit": eski_kilit, "fark": fark,
        "SECIM": SECIM, "ONCEKI": ONCEKI}
YENI = {"surum": yeni_surum, "kilit": yeni_kilit, "fark": fark,
        "SECIM": SECIM, "ONCEKI": ONCEKI}

ORNEKLER = """
>>> surum((1, 2))
'1.2'
>>> surum((3, 0))
'3.0'
>>> kilit(SECIM)
'olcum=1.2 ortak=3.2 rapor=1.1'
>>> kilit(ONCEKI)
'olcum=1.1 ortak=3.2 rapor=1.1'
>>> fark(SECIM, ONCEKI)
['olcum']
>>> fark(SECIM, SECIM)
[]
"""

EK_ORNEKLER = """
>>> set(surum((1, 2))) <= set('0123456789.')
True
>>> kilit(SECIM).count(',')
0
"""

# Duzyazi iddialar: metin, degisiklikten sonra bayat mi, ornege cevrilebilir mi.
DUZYAZI = (("sürüm metni yalnız rakam ve nokta taşır", True, True),
           ("alt sınır dahil, üst sınır dışlanmıştır", False, True),
           ("paketler ad sırasına göre yazılır", False, True),
           ("kilit metninde alanlar virgülsüz ayrılır", True, True),
           ("fark listesi ad sırasına göre verilir", False, True),
           ("önek yazılmaz, çünkü metin sayı gibi sıralanır", True, False))


def kosum(metin, kume):
    test = doctest.DocTestParser().get_doctest(metin, dict(kume), "belge", None, 0)
    sonuc = doctest.DocTestRunner(verbose=False).run(test, out=lambda s: None)
    return sonuc.attempted, sonuc.failed


BAYAT_DUZYAZI = sum(1 for _, b, _ in DUZYAZI if b)
CEVRILEN = sum(1 for _, b, c in DUZYAZI if b and c)
YAZIMLAR = (("düzyazı ağırlıklı", ORNEKLER, 0),
            ("iki iddia örnekte", ORNEKLER + EK_ORNEKLER, CEVRILEN))

print(f"{'belge yazımı':<19s} {'örnek':>6s} {'düzyazı':>8s} {'sesli bayat':>12s} "
      f"{'sessiz bayat':>13s}")
sesli, sessizler = [], []
for ad, metin, cevrilen in YAZIMLAR:
    denenen, dusen = kosum(metin, YENI)
    sessiz = BAYAT_DUZYAZI - cevrilen
    sesli.append(dusen)
    sessizler.append(sessiz)
    print(f"{ad:<19s} {denenen:6d} {len(DUZYAZI) - cevrilen:8d} {dusen:12d} "
          f"{sessiz:13d}")
print(f"iddia toplamı iki yazımda da {len(DUZYAZI) + kosum(ORNEKLER, YENI)[0]}, "
      f"bayatlayan {sesli[0] + BAYAT_DUZYAZI}")
print(f"sese dönen bayat iddia {sesli[0]} ve {sesli[1]}: "
      f"{len(set(sesli))} ayrı sonuç")
print(f"örneğe çevirmek {sessizler[0] - sessizler[1]} sessiz bayatlamayı sese "
      f"çevirdi; {sessizler[1]} tanesi gerekçe olduğu için çevrilemedi")
print(f"aynı belge değişiklikten önce {kosum(ORNEKLER, ESKI)[1]} ve "
      f"{kosum(ORNEKLER + EK_ORNEKLER, ESKI)[1]} başarısızlık verir")
```

```
belge yazımı         örnek  düzyazı  sesli bayat  sessiz bayat
düzyazı ağırlıklı        6        6            4             3
iki iddia örnekte        8        4            6             1
iddia toplamı iki yazımda da 12, bayatlayan 7
sese dönen bayat iddia 4 ve 6: 2 ayrı sonuç
örneğe çevirmek 2 sessiz bayatlamayı sese çevirdi; 1 tanesi gerekçe olduğu için çevrilemedi
aynı belge değişiklikten önce 0 ve 0 başarısızlık verir
```

## Aynı Bayatlama, İki Ayrı Sonuç

Son satır ölçümün başlangıç noktasını veriyor: değişiklikten önce her iki yazım da
**0** başarısızlık üretiyor. Belge, yazıldığı gerçekleştirimle uyumlu ve iddiaların
tamamı doğru. Bayatlama, biçim değiştiğinde doğuyor. Bu satır olmadan ölçümün geri kalanı
okunamazdı: düşen örneklerin bayatlamadan geldiğini söyleyebilmek için, değişiklikten önce
hiçbirinin düşmediğini göstermek gerekiyordu.

Değişiklikten sonra on iki iddianın **7**'si bayatlıyor: dördü çalıştırılabilir örnek,
üçü düzyazı. Bayat iddia sayısı iki yazımda da aynı — belgenin nasıl yazıldığı **neyin
yanlışlandığını** değiştirmiyor. Değiştirdiği tek şey, yanlışlanmanın **duyulup
duyulmadığı**.

Düzyazı ağırlıklı yazımda belge testi **4** başarısızlık veriyor ve **3** bayat iddia
sessiz kalıyor. İki bayat düzyazı iddia örneğe çevrildiğinde sesli sayı **6**'ya çıkıyor,
sessiz kalan **1**'e iniyor. Aynı bayatlama, iki belge yazımında **2 ayrı sonuç.**

Bu iki sayı arasındaki fark tam olarak yazımın kendisidir. Kod aynı, değişiklik aynı,
bayatlayan iddia kümesi aynı. Yalnız iki cümle düzyazıdan örneğe geçti ve bayatlamanın
görünürlüğü ikiden fazlasına yayıldı. Belge testinin ölçüme kattığı şey budur: **bir
iddiayı, yanlışlandığında konuşacak biçimde yazmak.**

Sesli sayının nereden geldiğine dikkat etmek gerekiyor. Dört çalıştırılabilir örnek
bayatladığı için düştü, ve düşmelerini biz işaretlemedik — belge testi koşturuldu ve sayı
okundu. Düzyazı iddiaların bayatlığı ise ölçülemedi, kâhinden işaretlendi: iki
gerçekleştirimi de biz yazdığımız için hangi cümlenin artık doğru olmadığını biliyoruz.
Ölçümün asimetrisi rastlantı değil, konunun kendisidir. **Ses çıkaran iddia sayılabilir,
sessiz kalan iddia ancak bilinebilir** — ve gerçek bir projede o bilgi de yoktur.

Bir başka okuma da şu: iki yazım arasındaki fark **2**, bayat düzyazı iddia sayısı ise
**3**'tü. Yani örneğe çevirme işlemi bayat düzyazı iddiaların hepsini kurtarmadı, üçte
ikisini kurtardı. Bu oran kurgunun bir seçimi değil, iddia sınıflarının doğal
dağılımının bir örneğidir: bir belgede her zaman değeri olmayan cümleler bulunur.

## Geriye Kalan

Sessiz kalan tek iddia gerekçedir ve orada kalmasının nedeni bir eksiklik değil, bir
sınırdır. Belge testi bir ifadeyi çalıştırıp değerini karşılaştırır; "çünkü" ile başlayan
bir cümlenin çalıştırılacak bir ifadesi yoktur. Bu iddia ancak bir insanın okumasıyla
denetlenebilir ve o denetimin nereye oturtulacağı Yazılım Geliştirme Pratiği müfredatının
konusudur.

Ölçümün burada söylediği şey, sessiz kalan sayının **sıfıra indirilemeyeceğidir.** Belge
testi sessiz bayatlamayı azaltır, ortadan kaldırmaz; kaldırabilseydi, bütün belge
çalıştırılabilir olurdu ve o zaman belge olmaktan çıkıp test olurdu. Bir belgenin değeri
de zaten yalnız sınanabilir cümlelerinde değil; okuyanı bir karara götüren cümlelerinde.

Ters yönde bir sınır daha var. Örneğe çevrilen her iddia, belgeyi **kırılganlaştırır**.
İkinci yazımdaki iki yeni örnek, sürüm metninin karakter kümesini ve kilit metnindeki
virgül sayısını sınıyor; bunlar davranışın kendisi değil, biçiminin ayrıntısı. Biçim
bilerek değiştirildiğinde bu örnekler de düşer ve düştüklerinde söyledikleri şey "kod
bozuldu" değil, "belge güncellenmeli" olur. Belge testinin yararı da zaten budur: iki
mesajı da aynı kanaldan, aynı anda verir.

Son olarak bir sayının ne olmadığını yazmak gerekiyor. **6/12**, belgenin yarısının
sınandığı anlamına gelmez; belgedeki iddiaların yarısının **yanlışlandığında ses
çıkardığı** anlamına gelir. Belgede yazmayan bir iddia bu ölçüme hiç girmez, ve bir
işlevin belgelenmemiş davranışı bu sayının tamamen dışındadır.

## Özet

- Bir belge dizgisindeki cümle de bir doğruluk iddiasıdır; farkı, hiçbir koşumun onu
  sınamamasıdır. Bağlandığı yüzey değiştiğinde sessizce yanlışlanır.
- Belge testi, belge metnindeki çağrıları çalıştırıp beklenen çıktıyla karşılaştırarak
  belgeyi bir test takımına dönüştürür; iddianın gömülü olması bir veri değil, bir
  **yazım seçimidir**.
- On iki iddianın **7**'si bir biçim değişikliğiyle bayatlar ve bu sayı yazımdan bağımsızdır;
  yazım yalnız bayatlamanın duyulup duyulmadığını belirler.
- Düzyazı ağırlıklı yazım **4** bayat iddiayı sese çevirir ve **3**'ünü sessiz bırakır; iki
  iddia örneğe çevrildiğinde sesli sayı **6**'ya çıkar — **2 ayrı sonuç**.
- Sessiz kalan son iddia bir gerekçedir ve örneğe çevrilemez: belge testi bir ifadenin
  değerini karşılaştırır, bir nedenin değeri yoktur.

## Sonraki Adım

Buraya kadar her ölçüm testin ne gördüğünü saydı: hangi testler keşfedildi, hangi sırada
koştular, hangi kaynağa baktılar, hangi iddia sese döndü. Hepsinin ortak yanı, sayılan
şeyin **testin bakışı** olmasıydı. Sonraki ders sayacı öbür tarafa çevirir ve kodun
kendisine bakar: üç testlik bir küme koştuğunda işlevin **hangi satırları yürüdü**, hangi
dalları alındı? Bu sayı bir ölçüde yanıltıcıdır ve dersin işi tam olarak o yanılmanın
sınırını çizmektir — sekiz satırın sekizi yürüdüğünde ve üç testin üçü geçtiğinde bile
işlevin sözleşmeye uymadığı bir çağrı bulunabilir.
