Yazılım Testi Nedir? Test Türleri ve Best Practices
"Test yazmaya vaktimiz yok." Bu cümle, bir yazılım projesinde duyulabilecek en tehlikeli cümlelerden biridir. Test yazmamak vakit kazandırmaz — ilerideki zaman kaybını bugüne ödünç verir.
Neden Test Yazmalıyız?
- Güven — Kodu değiştirirken bir şeyleri bozmadığınızdan emin olursunuz
- Dokümantasyon — Testler, kodun nasıl çalışması gerektiğini belgeler
- Refactoring kolaylığı — Testler olduğunda kodu güvenle yeniden yapılandırabilirsiniz
- Daha az bug — Hataları üretim ortamından önce yakalarsınız
- Hız — Uzun vadede geliştirme hızı artar
Test Piramidi
Mike Cohn'un test piramidi, testlerin ideal dağılımını gösterir:
╱╲
╱ ╲ E2E Tests (az, yavaş, pahalı)
╱────╲
╱ ╲ Integration Tests (orta)
╱────────╲
╱ ╲ Unit Tests (çok, hızlı, ucuz)
╱────────────╲
Unit Test (Birim Test)
En küçük kod birimlerini (fonksiyon, metod) izole olarak test eder:
// Fonksiyon
function calculateDiscount(price: number, isPremium: boolean): number {
if (isPremium) return price * 0.2;
if (price > 1000) return price * 0.1;
return 0;
}
// Unit test
describe('calculateDiscount', () => {
it('premium kullanıcıya %20 indirim uygulamalı', () => {
expect(calculateDiscount(500, true)).toBe(100);
});
it('1000 TL üzeri siparişe %10 indirim uygulamalı', () => {
expect(calculateDiscount(1500, false)).toBe(150);
});
it('normal sipariş için indirim uygulamamalı', () => {
expect(calculateDiscount(500, false)).toBe(0);
});
});
Integration Test (Entegrasyon Testi)
Birden fazla birimin birlikte çalışmasını test eder:
describe('Sipariş Akışı', () => {
it('sipariş oluşturulduğunda stok azalmalı', async () => {
const product = await createProduct({ stock: 10 });
await createOrder({ productId: product.id, quantity: 3 });
const updated = await getProduct(product.id);
expect(updated.stock).toBe(7);
});
});
E2E Test (Uçtan Uca Test)
Uygulamayı kullanıcının gözünden test eder:
// Cypress ile E2E test
describe('Giriş Akışı', () => {
it('geçerli bilgilerle giriş yapabilmeli', () => {
cy.visit('/login');
cy.get('#email').type('test@example.com');
cy.get('#password').type('password123');
cy.get('#login-btn').click();
cy.url().should('include', '/dashboard');
cy.contains('Hoş geldiniz').should('be.visible');
});
});
Test Araçları
| Araç | Dil/Platform | Tür | |------|-------------|-----| | Jest | JavaScript/TypeScript | Unit, Integration | | Vitest | Vite tabanlı projeler | Unit, Integration | | Cypress | Web | E2E | | Playwright | Web | E2E | | pytest | Python | Unit, Integration | | JUnit | Java | Unit |
Test-Driven Development (TDD)
Önce test yaz, sonra kodu yaz:
1. 🔴 Red — Geçmeyen test yaz
2. 🟢 Green — Testi geçirecek minimum kodu yaz
3. 🔵 Refactor — Kodu düzenle, test hâlâ geçmeli
4. Tekrarla
TDD Avantajları
- Daha iyi tasarım — Test edilebilir kod = temiz kod
- Yüksek kapsam — Test yazılmayan kod olmaz
- Güvenli refactoring — Her değişiklik test tarafından korunur
Test Best Practices
1. AAA Prensibi
Arrange — Hazırla (test verilerini kur)
Act — Eylem (test edilen kodu çalıştır)
Assert — Doğrula (sonucu kontrol et)
2. F.I.R.S.T
- Fast — Testler hızlı çalışmalı
- Independent — Testler birbirinden bağımsız olmalı
- Repeatable — Aynı sonucu her çalıştırmada vermeli
- Self-validating — Otomatik geçti/kaldı sonucu
- Timely — Kod yazılırken yazılmalı
3. Mock ve Stub Kullanımı
Dış bağımlılıkları (veritabanı, API) mock'layarak izole test edin:
jest.mock('./emailService', () => ({
sendEmail: jest.fn().mockResolvedValue(true)
}));
Sonuç
Test yazmak bir maliyet değil, bir yatırımdır. Başlangıçta zaman alır, ama projenin ömrü boyunca on kat geri döner. En azından kritik iş mantığı ve sık değişen kodlar için test yazarak başlayın.
Test yazma pratiklerini LabLudus platformunda interaktif görevlerle öğrenin.