YTM Dersleri: Bölüm 4
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.
Bu Sayfada
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.
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:
Yaşam Döngüsündeki Rollerin Özeti
| Durum | Sorumlu | Açıklama |
|---|---|---|
| New | Test Mühendisi | Hata ilk kez raporlanır; adımlar, beklenen/gerçekleşen sonuç, ekran görüntüsü eklenir. |
| Assigned | Test Lideri / PM | Uygun geliştiriciye yönlendirilir, öncelik (priority) ve şiddet (severity) belirlenir. |
| Open / In Progress | Geliştirici | Kök neden analizi yapılır, kod düzeltmesi yazılır. |
| Fixed | Geliştirici | Düzeltme tamamlanır, ilgili build/sürüme dahil edilir. |
| Retest | Test Mühendisi | Düzeltmenin sorunu gerçekten çözdüğü test edilerek doğrulanır. |
| Verified / Closed | Test Mühendisi | Sorun çözülmüştür, kayıt kapatılır ve arşivlenir. |
| Reopened | Test Mühendisi | Dü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:
⚠ 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.
🐞 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.
💥 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.
| Kriter | Error | Defect / Bug | Failure |
|---|---|---|---|
| Kaynağı | İnsan (düşünce/tasarım/kodlama hatası) | Kaynak kod / dokümantasyon | Çalışan sistem / üretim ortamı |
| Ne zaman oluşur | Geliştirme, tasarım veya analiz aşamasında | Kod yazıldığında (statik halde bulunur) | Program çalıştırıldığında (dinamik) |
| Nasıl tespit edilir | Kod incelemesi, eğitim, farkındalık | Statik analiz, code review, walkthrough | Test yürütme, kullanıcı gözlemi |
| Kim bulur | Genelde fark edilmez, sonrası izlenir | Geliştirici, test mühendisi, review ekibi | Test mühendisi, son kullanıcı |
| Örneği | Yanlış 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.
- Red: Henüz yazılmamış bir fonksiyonalite için önce başarısız olacak bir test yazılır.
- Green: Testi geçirecek en basit/minimum kod yazılır — mükemmellik hedeflenmez, sadece testin geçmesi önemlidir.
- 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)
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)
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
| Boyut | TDD | BDD |
|---|---|---|
| Test Seviyesi | Genelde birim (unit) test | Genelde kabul / entegrasyon seviyesi |
| Yazan Kişi | Geliştirici | İş birimi + test mühendisi + geliştirici (birlikte) |
| Amaç | Kodun beklenen şekilde çalıştığını doğrulamak | Sistemin iş gereksinimlerini karşıladığını doğrulamak |
| Hata Yönetimine Katkısı | Defect’leri kod seviyesinde erken yakalar | Yanlış 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.
