Yazılım Geliştirme

Yazılım Testi Nedir? Birim ve E2E Test

Birim, entegrasyon ve uçtan uca testlerin farkını, hangi testten ne kadar yazılması gerektiğini ve test otomasyonunun projeye kazandırdıklarını anlatıyoruz.

Aurora YazılımEditör ekibi 6 dk okuma
Yazılım Testi Nedir? Birim ve E2E Test
Yazılım testi nedir?

Yazılım testi, bir programın beklenen şekilde çalıştığını ve hata içermediğini doğrulamak için yapılan kontrollerin bütünüdür. Testler elle ya da kodla otomatik yapılabilir. En yaygın üç tür birim (unit) test, entegrasyon testi ve uçtan uca (E2E) testtir; sağlıklı bir projede bunlar bir piramit düzeninde dengelenir.

Yazılım Testi Nedir, Neden Gerekir?

Yazılım testi, yazdığınız kodun gerçekten istediğiniz şeyi yaptığını kanıtlama yoludur. Bir e-ticaret sitesinde indirim kodunun doğru hesaplanması, bir otel yazılımında aynı odaya iki rezervasyon yapılamaması ya da bir formun hatalı veriyi reddetmesi, testlerle güvence altına alınır.

Testsiz projelerde her yeni özellik, eskiden çalışan bir şeyi bozma riski taşır. Buna regresyon denir. Otomatik testler bu riski azaltır; değişiklik yapıldığında dakikalar içinde neyin bozulduğunu gösterir.

Hatanın bulunduğu an maliyeti belirler. Geliştirme sırasında yakalanan bir hata birkaç dakikada düzelir; canlı sistemde müşteri tarafından bulunan bir hata ise para, zaman ve güven kaybettirir.

Test Türleri: Birim, Entegrasyon, E2E

Test türleri, kapsadıkları alan ve çalışma hızlarına göre ayrılır. Küçük parçaları test etmek hızlı ve ucuzdur; bütün sistemi test etmek yavaş ama gerçekçidir.

TürKapsamHızBakım maliyeti
Birim testTek fonksiyon / bileşenÇok hızlıDüşük
Entegrasyon testiBirlikte çalışan parçalarOrtaOrta
E2E testKullanıcı akışının tamamıYavaşYüksek

Unit test nedir?

Unit test (birim testi), tek bir fonksiyonu ya da sınıfı dış dünyadan yalıtarak test eder. Veritabanı, ağ veya dosya sistemi devreye girmez; gerekirse sahte nesnelerle (mock) taklit edilir. Milisaniyeler içinde çalışır ve hatanın yerini nokta atışı gösterir.

Entegrasyon testi

Entegrasyon testi, birden fazla parçanın birlikte doğru çalıştığını doğrular: uygulama ile veritabanı, servis ile servis, sistem ile dış bir API. API nedir yazımızda anlattığımız uç noktalar en çok bu seviyede test edilir. Ödeme, kargo ve pazaryeri entegrasyonu gibi akışlarda bu testler kritik önemdedir.

E2E test

E2E test (uçtan uca test), sistemi gerçek bir kullanıcı gibi kullanır: tarayıcıyı açar, ürünü sepete ekler, ödeme adımına gider ve siparişin oluştuğunu kontrol eder. En gerçekçi testtir, ama en yavaş ve en kırılgan olanıdır.

Test Piramidi: Hangi Testten Ne Kadar?

Test piramidi, hangi test türünden ne kadar yazılması gerektiğini anlatan yaygın bir modeldir. Tabanda çok sayıda hızlı birim testi, ortada daha az entegrasyon testi, tepede ise yalnızca kritik akışları kapsayan az sayıda E2E test bulunur.

Piramidin tersine dönmesi, yani her şeyin E2E testle doğrulanmaya çalışılması sık yapılan bir hatadır. Bu durumda test süresi uzar, testler sebepsiz yere kırılır ve ekip zamanla testlere güvenmemeye başlar.

Kesin bir oran yoktur; proje türü belirleyicidir. Hesaplama ağırlıklı bir yazılımda birim testler ağır basarken, çok sayıda dış sisteme bağlanan bir projede entegrasyon testlerinin payı artar.

Jest ve Playwright ile Örnek

JavaScript dünyasında Jest ve Vitest birim testleri için, Playwright ve Cypress ise E2E testleri için yaygın tercihlerdir. Aşağıda bir indirim fonksiyonu için yazılmış basit bir birim testi görüyorsunuz.

Tür hatalarını daha test yazmadan yakalamak isterseniz TypeScript nedir yazımıza da bakın; tip sistemi, testlerin yükünü bir miktar hafifletir ama onların yerini tutmaz.

javascriptJest ile birim testi
// indirim.js
export function indirimUygula(tutar, oran) {
  if (oran < 0 || oran > 100) throw new Error('Geçersiz oran');
  return Math.round(tutar * (100 - oran)) / 100;
}

// indirim.test.js
import { indirimUygula } from './indirim.js';

test('yüzde 20 indirim doğru hesaplanır', () => {
  expect(indirimUygula(200, 20)).toBe(160);
});

test('geçersiz oran hata verir', () => {
  expect(() => indirimUygula(200, 120)).toThrow();
});
javascriptPlaywright ile E2E testi
import { test, expect } from '@playwright/test';

test('ürün sepete eklenir', async ({ page }) => {
  await page.goto('https://ornek-magaza.test/urun/zeytinyagi');
  await page.getByRole('button', { name: 'Sepete Ekle' }).click();
  await expect(page.getByTestId('sepet-adet')).toHaveText('1');
});

Test Otomasyonu ve CI Süreci

Test otomasyonu, testlerin elle değil, her kod değişikliğinde otomatik olarak çalıştırılmasıdır. Kod depoya gönderildiğinde bir CI (sürekli entegrasyon) hattı testleri çalıştırır; testlerden biri başarısızsa değişiklik canlıya alınmaz.

Bu düzen, ekip büyüdükçe daha da değerli hâle gelir. Herkes aynı kalite çıtasına tabi olur ve hatalar müşteriye ulaşmadan yakalanır.

  1. Geliştirici değişikliği bir dalda yapar ve depoya gönderir.
  2. CI hattı bağımlılıkları kurar, birim ve entegrasyon testlerini çalıştırır.
  3. Kritik akışlar için E2E testleri test ortamında koşar.
  4. Tüm testler geçerse kod incelemesinin ardından canlıya alınır.

Diğer Test Türleri

Doğru çalışmak tek başına yetmez; yazılımın hızlı, güvenli ve kullanılabilir olması da gerekir. Bu yüzden işlevsel testlerin yanında başka test türleri de vardır.

  • Performans testi: Yük altında sistemin nasıl davrandığını ölçer. Sayfa hızı tarafı hız ve performans yönetimi çalışmasının da parçasıdır.
  • Güvenlik testi: Yetkisiz erişim, enjeksiyon ve benzeri açıkları arar.
  • Kullanılabilirlik testi: Gerçek kullanıcıların arayüzü zorlanmadan kullanıp kullanamadığına bakar; UI/UX tasarım sürecinin doğal parçasıdır.
  • Erişilebilirlik testi: Ekran okuyucu ve klavye kullanıcıları için uygunluğu denetler.
  • Görsel regresyon testi: Ekran görüntülerini karşılaştırarak beklenmeyen tasarım kaymalarını yakalar.
  • Derlenmiş modül testleri: WebAssembly nedir yazımızda anlattığımız Wasm modülleri gibi parçalar da kendi test hattına ihtiyaç duyar.

Sık Yapılan Test Hataları

Test yazmak bir beceridir; kötü yazılmış testler yardımcı olmak yerine yük olabilir. En yaygın hatalar şunlardır.

  • Kapsama yüzdesine takılmak: Yüksek oran, iyi test anlamına gelmez; önemli olan kritik davranışların test edilmesidir.
  • Uygulamanın iç yapısını test etmek: Kod yeniden düzenlendiğinde testler sebepsiz kırılır. Davranışı test edin.
  • Kırılgan E2E testler: Sabit bekleme süreleri yerine elemanın görünmesini bekleyen yapılar kullanın.
  • Testleri canlı veriye bağlamak: Testler kendi verisini hazırlamalı ve sonra temizlemelidir.
  • Başarısız testi devre dışı bırakıp unutmak: Bu, testlere duyulan güveni hızla yok eder.

Teste Nereden Başlamalı?

Hiç testi olmayan bir projeye bir anda yüzlerce test eklemek gerçekçi değildir. Daha verimli yol, en riskli yerden başlayıp kademeli ilerlemektir. Her düzeltilen hata için bir test yazmak bile birkaç ay içinde ciddi bir güvenlik ağı oluşturur.

Başlangıçta mükemmel kapsama değil, güvenilir testler hedeflenmelidir. Az ama her seferinde tutarlı sonuç veren testler, çok sayıda kararsız testten daha değerlidir.

  1. Para, stok ve kullanıcı verisiyle ilgili fonksiyonları listeleyin.
  2. Bu fonksiyonlar için önce birim testleri yazın.
  3. Dış sistemlere bağlanan noktalara entegrasyon testi ekleyin.
  4. En kritik iki üç kullanıcı akışı için E2E testi kurun.
  5. Testleri CI hattına bağlayın ve kırmızı testle canlıya çıkmayın.

Testler İşletmeye Ne Kazandırır?

İşletme sahibi için test, görünmeyen ama hissedilen bir yatırımdır. Özel yazılım çözümleri geliştirilirken kritik akışların test altına alınması bu yüzden önemlidir. Kampanya günü çöken bir ödeme sayfası ya da yanlış stok gösteren bir mağaza, test maliyetinden çok daha pahalıya patlar.

Sipariş, fatura ve stok akışları birden fazla sistem arasında dolaştığında hata ihtimali artar. Bu yüzden e-ticaret entegrasyonu ve e-ticaret altyapısı projelerinde test edilmiş, öngörülebilir bir yapı kurmak uzun vadede bakım maliyetini düşürür.

Sık Sorulan Sorular

01Küçük bir proje için test yazmak gerekir mi?

Her satırı test etmeniz gerekmez, ama para veya veriyle ilgili kritik fonksiyonlar mutlaka test edilmelidir. Küçük başlamak, ileride proje büyüdüğünde güvenle değişiklik yapmanızı sağlar.

02Manuel test tamamen gereksiz mi?

Hayır. Keşif amaçlı manuel testler, otomasyonun öngörmediği sorunları bulur. Tekrarlayan kontroller otomatikleştirilmeli, insan gözü ise yeni özellikleri ve deneyimi değerlendirmeye ayrılmalıdır.

03TDD nedir?

Test güdümlü geliştirme (TDD), önce başarısız olan testi yazıp ardından testi geçirecek kodu yazma yöntemidir. Tasarımı sadeleştirir ve testsiz kod kalmasını önler; ancak ekibin bu disipline alışması zaman alır.

04Jest mi Vitest mi kullanmalıyım?

İkisi de birim testleri için olgun araçlardır ve sözdizimleri benzerdir. Vite tabanlı projelerde Vitest daha kolay entegre olur; mevcut büyük projelerde Jest yaygınlığıyla öne çıkar.

Yazılım testi, hataları müşteriden önce yakalamanın ve yazılımı güvenle büyütmenin yoludur. Birim testleri temel alıp kritik akışları E2E testlerle güvenceye alan dengeli bir yapı, uzun vadede en düşük maliyetli yoldur. Test edilmiş, sürdürülebilir bir yazılım için Aurora'nın yazılım çözümlerini ve entegrasyon hizmetlerini inceleyebilirsiniz.