Sobes.tech
Middle

Testler ve TDD metodolojisi kod organizasyonunu nasıl etkiler?

sobes.tech yapay zeka

AI'dan gelen yanıt

Testler ve TDD, kodun organizasyonu üzerinde önemli bir etki yapar:

  1. Bölme ve modülerlik: Testleri geliştirme öncesinde veya sırasında yazmak, küçük ve kolay test edilebilir fonksiyonlar ve bileşenler oluşturmayı teşvik eder, bu da modülerliği artırır ve kodun bağlılığını azaltır.

  2. Temizlik ve anlaşılırlık: Testler, canlı belge ve kod kullanım örnekleri olarak hizmet eder. Kötü tasarlanmış ve karmaşık (spagetti kodu) kodlar için test yazmak zordur. Bu, daha temiz ve anlaşılır kod yazmayı teşvik eder.

  3. API geliştirme: Test yazma süreci, oluşturulan modüllerin API'sini dışarıdan kullanmaya zorlar. Bu, API'nin rahatsız edici veya mantıksız kısımlarını erken aşamada tespit etmeye ve geliştirmeye yardımcı olur.

  4. Refaktörleme desteği: Kapsamlı bir test setine sahip olmak, refaktörleme sırasında güven sağlar. Testler, regresyonları hızla tespit eder ve iç yapıyı güvenli bir şekilde değiştirmeye olanak tanır, dış davranışı bozmadan.

  5. Hızlı hata tespiti: Testler, hataları geliştirme aşamalarında tespit etmeye olanak tanır, bu da hataların üretimde tespit edilmesine kıyasla giderme maliyetini önemli ölçüde azaltır.

TDD'den ilham alan kod organizasyonu örneği (Golang'de):

package calculator // Belirli bir fonksiyonellik için paket

import "errors" // Bağımlılıklar

// Add iki tam sayıyı toplar.
func Add(a, b int) int {
	return a + b // Basit mantık
}

// Divide, num'u den'e böler. den 0 ise hata döner.
func Divide(num, den int) (int, error) {
	if den == 0 {
		// Sınır durumlarının açık işlenmesi, kolay test edilir
		return 0, errors.New("sıfıra bölme kabul edilmez")
	}
	return num / den, nil
}

İlgili testler:

package calculator // Aynı pakette, ancak ayrı bir dosyada (_test.go)

import (
	"testing"
)

// TestAdd, Add fonksiyonunu test eder.
func TestAdd(t *testing.T) {
	// Farklı girişler için test vakaları
	testCases := []struct {
		name   string
		a, b   int
		expected int
	}{
		{"Pozitif Sayılar", 1, 2, 3},
		{"Negatif Sayılar", -1, -2, -3},
		{"Karışık Sayılar", -1, 2, 1},
		{"Sıfır ve Pozitif", 0, 5, 5},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) { // t.Run kullanımıyla testleri yapılandırma
			result := Add(tc.a, tc.b) // Test edilen fonksiyon çağrısı
			if result != tc.expected {
				// Açık hata mesajı
				t.Errorf("Add(%d, %d): Beklenen %d, alınan %d", tc.a, tc.b, tc.expected, result)
			}
		})
	}
}

// TestDivide, Divide fonksiyonunu test eder.
func TestDivide(t *testing.T) {
	testCases := []struct {
		name        string
		num, den    int
		expected int
		expectError bool
	}{
		{"Pozitif Bölme", 10, 2, 5, false},
		{"Negatif Sonuç", 10, -2, -5, false},
		{"Bir ile bölme", 7, 1, 7, false},
		{"Sıfıra bölme", 5, 0, 0, true}, // Hata durumu
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			result, err := Divide(tc.num, tc.den)

			if tc.expectError {
				if err == nil {
					// Beklenen hatanın kontrolü
					t.Errorf("Divide(%d, %d): Hata bekleniyordu, ama alınmadı", tc.num, tc.den)
				}
			} else {
				if err != nil {
					// Hatanın olmamasının kontrolü
					t.Errorf("Divide(%d, %d): Beklenmeyen hata: %v", tc.num, tc.den, err)
				}
				if result != tc.expected {
					// Başarılı sonuç kontrolü
					t.Errorf("Divide(%d, %d): Beklenen %d, alınan %d", tc.num, tc.den, tc.expected, result)
				}
			}
		})
	}
}