Yazılım Test Mühendisliği Dersleri

YTM Dersleri: Bölüm 4

Hata Yönetimi | Hata Yaşam Döngüsü, Error/Defect/Failure, TDD & BDD | yazilimtestmuhendisligi.com

Hata Yönetimi: Yaşam Döngüsü, Error / Defect / Failure Ayrımı ve TDD ile BDD Yaklaşımları

Yazılım kalitesinin temeli, hataların nasıl ortaya çıktığını, nasıl sınıflandırıldığını ve geliştirme sürecine nasıl erken entegre edilerek önlenebileceğini anlamaktan geçer. Bu rehberde hata yaşam döngüsünü, kavramsal farkları ve modern geliştirme yaklaşımlarını adım adım inceliyoruz.

Hata Yaşam Döngüsü Error vs Defect vs Failure Test Driven Development Behavior Driven Development

i Hata Yönetimi Nedir?

Hata yönetimi (Defect Management), bir yazılım ürününde tespit edilen hataların kaydedilmesinden, sınıflandırılmasından, öncelik/önem derecesinin belirlenmesinden, çözülmesinden ve doğrulanmasından sorumlu olan sistematik süreçtir. Amaç yalnızca hatayı “kapatmak” değil; hatanın kök nedenini anlamak, tekrarını önlemek ve yazılım kalitesini sürekli iyileştirmektir.

İyi kurulmuş bir hata yönetimi süreci; geliştirici, test mühendisi, ürün sahibi ve proje yöneticisi arasında ortak bir dil ve şeffaf bir takip mekanizması sağlar (örn. Jira, Azure DevOps, Bugzilla gibi araçlarla).

Bu sürecin sağlıklı işleyebilmesi için önce temel bir ayrımı netleştirmek gerekir: bir insan hatasının (error), kod içindeki kusurdan (defect) ve kullanıcının gözlemlediği arızadan (failure) farklı olduğunu bilmek. Ayrıca hataların doğumundan kapatılmasına kadar geçtiği standart bir yaşam döngüsünü anlamak gerekir. Aşağıdaki bölümlerde bu iki temel konuyu, ardından hataları en baştan azaltmayı hedefleyen TDD ve BDD yaklaşımlarını detaylı olarak ele alıyoruz.

1 Hata Yaşam Döngüsü (Bug / Defect Life Cycle)

Bir hata, test sürecinde tespit edildiği andan itibaren belirli durumlardan (status) geçerek kapanışa ulaşır. Bu döngü, ekipten ekibe küçük farklılıklar gösterse de genel akış aşağıdaki gibidir:

Yeni (New)Test mühendisi hatayı bulur ve kaydeder
Atandı (Assigned)Lider/PM ilgili geliştiriciye atar
Açık (Open)Geliştirici inceler, üzerinde çalışır
Düzeltildi (Fixed)Kod düzeltilir, build’e alınır
Yeniden Test (Retest)Test mühendisi doğrular
Doğrulandı (Verified)Çözüm onaylanır
Kapatıldı (Closed)Hata yaşam döngüsü biter
↑↓
Yeniden Açıldı (Reopened)Düzeltme yetersizse Open durumuna döner
Diğer olası durumlar: Duplicate (Mükerrer — aynı hata daha önce kaydedilmiş), Rejected (Reddedildi — bu bir hata değil / beklenen davranış), Deferred (Ertelendi — sonraki sürüme bırakıldı), Not Reproducible (Tekrarlanamıyor — hata ortamı sağlanamıyor).

Yaşam Döngüsündeki Rollerin Özeti

DurumSorumluAçıklama
NewTest MühendisiHata ilk kez raporlanır; adımlar, beklenen/gerçekleşen sonuç, ekran görüntüsü eklenir.
AssignedTest Lideri / PMUygun geliştiriciye yönlendirilir, öncelik (priority) ve şiddet (severity) belirlenir.
Open / In ProgressGeliştiriciKök neden analizi yapılır, kod düzeltmesi yazılır.
FixedGeliştiriciDüzeltme tamamlanır, ilgili build/sürüme dahil edilir.
RetestTest MühendisiDüzeltmenin sorunu gerçekten çözdüğü test edilerek doğrulanır.
Verified / ClosedTest MühendisiSorun çözülmüştür, kayıt kapatılır ve arşivlenir.
ReopenedTest MühendisiDüzeltme yetersiz veya hatalı ise döngü tekrar açık duruma döner.

2 Error / Defect / Failure Ayrımı

Yazılım testinde en sık karıştırılan üç terim Error, Defect (Bug) ve Failure‘dır. Bunlar aslında aynı sorunun farklı aşamalardaki halleridir:

İnsan Hatası (Error) Koddaki Kusur (Defect) Gözlemlenen Arıza (Failure)

⚠ Error (Hata)

Bir geliştiricinin, analistin ya da tasarımcının yaptığı insan kaynaklı yanlışlıktır. Yanlış mantık kurma, eksik gereksinim anlama veya dikkatsizlik sonucu ortaya çıkar. Henüz kodda somutlaşmış olmayabilir; düşünce/tasarım aşamasında da oluşabilir.

Örnek: Geliştirici, indirim oranı hesaplamasında yüzde işlemini yanlış kurgular.

🐞 Defect / Bug (Kusur)

Error’ın kod içinde somut bir sonucudur; yazılımın kaynak kodunda bulunan yanlış veya eksik bir durumdur. Statiktir — çalıştırılmadan da kod incelemesiyle (code review) bulunabilir.

Örnek: Kodda “indirim * 100” yerine yanlışlıkla “indirim / 100” yazılmıştır.

💥 Failure (Arıza)

Defect’in program çalıştırıldığında dışarıya yansıyan, gözlemlenebilir sonucudur. Beklenen davranış ile gerçekleşen davranış arasındaki farktır; kullanıcı veya test mühendisi tarafından fark edilir.

Örnek: Kullanıcı 100 TL’lik ürüne %10 indirim uyguladığında ekranda yanlış tutar (110 TL) görünür.
Önemli not: Her Defect mutlaka bir Failure’a yol açmaz. Örneğin hiçbir zaman çalıştırılmayan (dead code) bir kod parçasındaki defect, kullanıcı tarafından hiçbir zaman failure olarak gözlemlenmeyebilir. Bu yüzden test kapsamının (coverage) genişliği büyük önem taşır.
KriterErrorDefect / BugFailure
Kaynağıİnsan (düşünce/tasarım/kodlama hatası)Kaynak kod / dokümantasyonÇalışan sistem / üretim ortamı
Ne zaman oluşurGeliştirme, tasarım veya analiz aşamasındaKod yazıldığında (statik halde bulunur)Program çalıştırıldığında (dinamik)
Nasıl tespit edilirKod incelemesi, eğitim, farkındalıkStatik analiz, code review, walkthroughTest yürütme, kullanıcı gözlemi
Kim bulurGenelde fark edilmez, sonrası izlenirGeliştirici, test mühendisi, review ekibiTest mühendisi, son kullanıcı
ÖrneğiYanlış iş kuralı anlaşılması“if (x > 10)” yerine “if (x >= 10)” yazılması gerekirken yanlış yazılmasıSınır değer girildiğinde uygulamanın yanlış sonuç vermesi

3 Test Driven Development (TDD)

Test Güdümlü Geliştirme (TDD), kodu yazmadan önce o kodun testini yazma prensibine dayanan bir yazılım geliştirme yaklaşımıdır. Amaç, hataları en erken aşamada, kod daha yazılmadan önce tanımlanan beklentilerle sınırlandırmaktır. TDD, ünlü “Kırmızı – Yeşil – Refactor” döngüsü ile çalışır.

REDBaşarısız test yaz
GREENTesti geçecek minimum kod yaz
REFACTORKodu temizle, testler yeşil kalsın
  1. Red: Henüz yazılmamış bir fonksiyonalite için önce başarısız olacak bir test yazılır.
  2. Green: Testi geçirecek en basit/minimum kod yazılır — mükemmellik hedeflenmez, sadece testin geçmesi önemlidir.
  3. Refactor: Test yeşil kalırken kod kalitesi, okunabilirliği ve performansı iyileştirilir.

Basit TDD Örneği (Python — pytest)

# 1. ADIM - RED: Önce test yazılır (henüz "hesapla_indirim" fonksiyonu yok)
def test_hesapla_indirim():
    assert hesapla_indirim(100, 10) == 90

# 2. ADIM - GREEN: Testi geçirecek minimum kod yazılır
def hesapla_indirim(tutar, yuzde):
    return tutar - (tutar * yuzde / 100)

# 3. ADIM - REFACTOR: Kod iyileştirilir, testler yeşil kalmaya devam eder
def hesapla_indirim(tutar: float, yuzde: float) -> float:
    if not (0 <= yuzde <= 100):
        raise ValueError("Yüzde 0-100 aralığında olmalıdır")
    return round(tutar * (1 - yuzde / 100), 2)
TDD’nin faydaları: Erken hata yakalama, güvenli refactoring, yaşayan dokümantasyon (testler kodun nasıl davranması gerektiğini gösterir), daha az defect ile üretime çıkış ve geliştiriciye anlık geri bildirim.

4 Behavior Driven Development (BDD)

Davranış Güdümlü Geliştirme (BDD), TDD’nin bir uzantısı olarak doğmuştur. Farkı, testlerin/senaryoların teknik dilde değil, iş birimi (business), test mühendisi ve geliştiricinin ortak anlayabileceği doğal dile yakın bir dilde (genellikle Gherkin sözdizimi ile Given – When – Then yapısında) yazılmasıdır. Böylece gereksinimler doğrudan çalıştırılabilir test senaryolarına dönüşür.

Gherkin Sözdizimi ile Örnek Senaryo

Özellik: Sepette İndirim Uygulama

  Senaryo: Geçerli kupon kodu ile indirim uygulanması
    Given kullanıcının sepetinde 100 TL tutarında ürün var
    And "INDIRIM10" adında geçerli bir kupon kodu mevcut
    When kullanıcı kupon kodunu sepete uygular
    Then sepet toplamı 90 TL olarak güncellenmelidir
    And ekranda "Kupon başarıyla uygulandı" mesajı gösterilmelidir

Bu senaryo, otomasyon araçlarıyla (örn. Cucumber, SpecFlow, Behave) doğrudan kod adımlarına bağlanıp çalıştırılabilir hale getirilir:

# step_definitions.py (Python + behave)
from behave import given, when, then

@given('kullanıcının sepetinde {tutar} TL tutarında ürün var')
def step_sepet_olustur(context, tutar):
    context.sepet = Sepet(tutar=float(tutar))

@when('kullanıcı kupon kodunu sepete uygular')
def step_kupon_uygula(context):
    context.sepet.kupon_uygula("INDIRIM10")

@then('sepet toplamı {beklenen} TL olarak güncellenmelidir')
def step_toplam_kontrol(context, beklenen):
    assert context.sepet.toplam == float(beklenen)
BDD’nin faydaları: İş birimi ile teknik ekip arasındaki iletişim kopukluğunu azaltır, gereksinimler net ve test edilebilir hale gelir, “yaşayan dokümantasyon” oluşturur ve kabul kriterlerinin (acceptance criteria) baştan netleşmesini sağlar.

5 TDD ve BDD Karşılaştırması

TDD ve BDD birbirini dışlayan değil, birbirini tamamlayan yaklaşımlardır. Pratikte pek çok ekip her ikisini bir arada kullanır: BDD ile üst seviye kabul kriterleri, TDD ile birim (unit) seviyesinde teknik detaylar doğrulanır.

TDD

  • Odak noktası: Kodun teknik doğruluğu
  • Hedef kitle: Geliştiriciler
  • Dil: Programlama dili (unit test framework’leri)
  • Döngü: Red – Green – Refactor
  • Örnek araçlar: JUnit, pytest, NUnit, xUnit

BDD

  • Odak noktası: Sistemin davranışı / iş değeri
  • Hedef kitle: İş birimi, ürün sahibi, test mühendisi, geliştirici
  • Dil: Doğal dile yakın (Gherkin: Given/When/Then)
  • Döngü: Senaryo tanımla – Otomatikleştir – Doğrula
  • Örnek araçlar: Cucumber, SpecFlow, Behave, JBehave
BoyutTDDBDD
Test SeviyesiGenelde birim (unit) testGenelde kabul / entegrasyon seviyesi
Yazan KişiGeliştiriciİş birimi + test mühendisi + geliştirici (birlikte)
AmaçKodun beklenen şekilde çalıştığını doğrulamakSistemin iş gereksinimlerini karşıladığını doğrulamak
Hata Yönetimine KatkısıDefect’leri kod seviyesinde erken yakalarYanlış anlaşılan gereksinimlerden doğan hataları (error) en başta önler

Sonuç ve Öneriler

Etkili bir hata yönetimi stratejisi, sadece hataları kaydetmekle kalmaz; onların nereden geldiğini (Error), nasıl koda yansıdığını (Defect) ve nasıl gözlemlendiğini (Failure) anlayarak kök nedene inmeyi hedefler. Bunun yanında hataların standart bir yaşam döngüsü içinde izlenmesi, ekipler arası şeffaflığı ve hesap verebilirliği artırır.

En güçlü strateji ise hatayı bulmak değil, en baştan önlemektir. Bu noktada TDD geliştiricilere kod seviyesinde erken geri bildirim sağlarken, BDD iş birimi ile teknik ekip arasındaki anlaşma farklılıklarından (Error’ın en yaygın kaynağı) doğan hataları en başından engeller. İkisinin birlikte kullanılması, hem teknik olarak sağlam hem de iş ihtiyaçlarını doğru karşılayan yazılımlar üretmenin en etkili yollarından biridir.

Pratik öneri: Küçük bir projede önce BDD ile kritik kullanıcı senaryolarını Gherkin formatında yazın, ardından bu senaryoları destekleyecek birim testlerini TDD döngüsüyle geliştirin. Bu ikili yaklaşım, hem hata yaşam döngüsündeki “New” aşamasına giren kayıt sayısını azaltır hem de ekip içi iletişimi güçlendirir.
Başa Dön →

yazilimtestmuhendisligi.com — Nihat Ük

Bu içerik eğitim amaçlı hazırlanmıştır. © 2026

Yorum bırakın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir