En İyi Uygulamalar ve İpuçları 🎯

Gorkem KARA
4 min readAug 5, 2024

--

Merhaba arkadaşlar! Bir önceki makalede, unit testlerin gücünü ve nasıl yazılacağını öğrendik. Bu makalede ise, test yazarken dikkate almanız gereken en iyi uygulamaları ve ipuçlarını paylaşacağız. Testlerinizin daha etkili, sürdürülebilir ve okunabilir olmasını sağlayacak bu ipuçlarına dikkat ederseniz, daha sağlam ve güvenilir yazılımlar geliştirebilirsiniz. Hazırsanız başlayalım!

En İyi Uygulamalar

1. Anlamlı ve Açıklayıcı Test İsimleri

Test isimleriniz, testin ne yaptığını ve neyi doğruladığını açıkça belirtmelidir. Bu, testlerin okunabilirliğini ve bakımını kolaylaştırır.

Kötü Örnek:

@Test
fun test1() {
// Bu testin ne yaptığını anlamak zor
val calculator = Calculator()
val result = calculator.add(2, 3)
assertEquals(5, result)
}

@Test
fun test2() {
// Bu testin neyi test ettiğini anlamak zor
val calculator = Calculator()
val result = calculator.subtract(5, 3)
assertEquals(2, result)
}

İyi Örnek:

@Test
fun `when adding two numbers result is correct`() {
// Bu test, iki sayının toplamını kontrol ediyor
val calculator = Calculator()

val result = calculator.add(2, 3)

// Beklenen sonuç 5 olmalı
assertEquals(5, result)
}

@Test
fun `when subtracting two numbers result is correct`() {
// Bu test, iki sayının farkını kontrol ediyor
val calculator = Calculator()

val result = calculator.subtract(5, 3)

// Beklenen sonuç 2 olmalı
assertEquals(2, result)
}

2. Her Test Bağımsız Olmalı

Her test, bağımsız ve izole çalışmalıdır. Bir test diğer testlere bağımlı olmamalıdır. Bu, testlerin sırasız çalışabilmesini sağlar ve testler arasında yan etki oluşmasını engeller.

Kötü Örnek:

@Test
fun testA() {
// Bu test, bazı sonuçlara dayanıyor ve bağımsız değil
val result = someFunction()
assertEquals(expectedValue, result)
}

@Test
fun testB() {
// Bu test, başka bir teste bağlı olabilir ve bağımsız çalışmayabilir
val result = anotherFunction()
assertEquals(expectedValue, result)
}

İyi Örnek:

@Test
fun `function should return expected value`() {
// Bu test, bağımsız olarak çalışıyor ve diğer testlere bağlı değil
val result = someFunction()
assertEquals(expectedValue, result)
}

@Test
fun `another function should return expected value`() {
// Bu test, bağımsız olarak çalışıyor ve diğer testlere bağlı değil
val result = anotherFunction()
assertEquals(expectedValue, result)
}

3. Given-When-Then Yaklaşımı

Testlerinizde Given-When-Then yaklaşımını kullanarak, testin hangi aşamalardan geçtiğini açıkça belirtebilirsiniz. Bu yaklaşım, testin anlaşılmasını ve bakımını kolaylaştırır.

Given-When-Then Yaklaşımı

Given: Testin başlangıç durumu ve hazırlıkları.

When: Test edilen işlemin gerçekleştirilmesi.

Then: Testin sonucunun doğrulanması.

Örnek 1: Kullanıcı Yetişkinlik Kontrolü

@Test
fun `when user is adult returns true`() {
// Given: Test verisi hazırlanıyor
val user = User("1", "John Doe", "john@example.com", 25)

// When: Fonksiyon çağrılıyor
val result = repository.isUserAdult(user)

// Then: Sonuç kontrol ediliyor
assertTrue(result)
}

Örnek 2: Toplama İşlemi

@Test
fun `when adding two numbers result is correct`() {
// Given: Hesap makinesi nesnesi oluşturuluyor
val calculator = Calculator()

// When: İki sayı toplanıyor
val result = calculator.add(2, 3)

// Then: Sonuç kontrol ediliyor
assertEquals(5, result)
}

Örnek 3: Kullanıcı E-posta Güncellemesi

@Test
fun `when updating user email then email is updated correctly`() {
// Given: Bir kullanıcı oluşturuluyor
val user = User("1", "John Doe", "john@example.com", 25)
val newEmail = "new.email@example.com"

// When: Kullanıcının e-postası güncelleniyor
val updatedUser = repository.updateUserEmail(user, newEmail)

// Then: Güncellenmiş kullanıcı verisi kontrol ediliyor
assertNotNull(updatedUser)
assertEquals(newEmail, updatedUser.email)
assertEquals(user.id, updatedUser.id)
assertEquals(user.name, updatedUser.name)
assertEquals(user.age, updatedUser.age)
}

4. Mocking Kullanımı

Bağımlılıkları izole etmek ve gerçek servislerle etkileşimden kaçınmak için mocking kullanın. Bu, testlerin hızlı ve güvenilir olmasını sağlar.

5. Test Veri Hazırlığı

Testleriniz için gerekli verileri hazırlamak ve tekrar kullanılabilir hale getirmek için yardımcı fonksiyonlar veya sınıflar oluşturun. Bu, test kodunu daha temiz ve anlaşılır hale getirir.

Örnek:

fun createTestUser(id: String, name: String, email: String, age: Int): User {
return User(id, name, email, age)
}

6. Hataları ve Edge Case’leri Test Edin

Testlerinizde sadece mutlu patikaları değil, aynı zamanda hata durumlarını ve edge case’leri de test edin. Bu, yazılımınızın daha sağlam olmasını sağlar.

Örnek:

@Test(expected = IllegalArgumentException::class)
fun `division by zero throws exception`() {
// Given: Hesap makinesi nesnesi oluşturuluyor
val calculator = Calculator()

// When-Then: 0'a bölünme durumu test ediliyor
calculator.divide(5, 0)
}

Test Yazarken Dikkat Edilmesi Gereken İpuçları

1. Kod Kapsamını Kontrol Edin

Testlerinizin kod kapsamını kontrol edin ve mümkün olduğunca yüksek bir kapsama oranı sağlamaya çalışın. Bu, tüm kodunuzun test edildiğini ve potansiyel hataların yakalandığını garanti eder.

2. Performans ve Hız

Testlerinizi hızlı ve verimli tutun. Uzun süren testler, geliştirme sürecini yavaşlatabilir. Performansı artırmak için mocking ve izole testler kullanın.

3. Okunabilirlik

Test kodunuzun okunabilirliğine dikkat edin. Karmaşık ve anlaşılması zor testler, bakımını zorlaştırır ve hatalara neden olabilir.

4. Sürekli Entegrasyon (CI)

Testlerinizi sürekli entegrasyon (CI) sistemine entegre edin. Bu, her kod değişikliğinde testlerin otomatik olarak çalışmasını sağlar ve hataların erken aşamada yakalanmasını sağlar.

5. Testlerin Dokümantasyonu

Testlerinizi dokümante edin. Hangi testlerin neyi doğruladığını ve nasıl çalıştığını açıklayan dokümantasyon, takım arkadaşlarınızın ve sizin testleri daha iyi anlamanızı sağlar.

Özet ve Sonuç

Bu makalede, test yazarken dikkat etmeniz gereken en iyi uygulamaları ve ipuçlarını paylaştık. Anlamlı test isimleri, bağımsız testler, Given-When-Then yaklaşımı, mocking kullanımı, test veri hazırlığı ve edge case’leri test etmenin önemini vurguladık. Ayrıca, kod kapsamı, performans, okunabilirlik, sürekli entegrasyon ve testlerin dokümantasyonu gibi konulara değindik. Bir sonraki makalede, projeyi tamamlama ve sonuçlandırma adımlarını ele alacağız. Takipte kalın!

Diğer Makaleler

1. Android UI Testlerine Giriş 📱
2. Espresso ile İleri Düzey UI Testleri 📈
3. UI Automator ile Gelişmiş UI Testleri 🔍
Önceki Makale -> Unit Testlerin Gücü 💪
Sonraki Makale -> Projeyi Tamamlama ve Sonuç 🏁

--

--