REACT TESTING STRATEJİSİ

State of JS 2023 raporuna göre React ekosisteminde test yazan geliştiricilerin %84'ü React Testing Library tercih ediyor, Enzyme'ın payı %12'ye düşmüş durumda. Aynı raporda dikkat çeken başka bir veri var: ekiplerin %47'si testlerinin "yanlış yerde" yoğunlaştığını söylüyor — yani snapshot ve UI ayrıntılarına gömülmüş, davranışı doğrulamayan testler. Test pyramid bu dengesizliği çözmek için var: çok sayıda hızlı unit test, ortada davranış odaklı integration, tepede az sayıda kritik e2e.
1. Test Pyramid Oranları ve React Bağlamı
Mike Cohn'un orijinal test pyramid önerisi yaklaşık %70 unit, %20 integration, %10 e2e şeklindeydi. Ancak React gibi component tabanlı kütüphanelerde bu oran kayıyor. Kent C. Dodds'un "Testing Trophy" yaklaşımı, integration testlerin tepe noktası olduğunu savunuyor çünkü bir component'in render edilmesi, prop alması ve event tetiklemesi zaten birden fazla birim kapsar.
- Unit (%30-40): Pure function, custom hook, util — Jest yeterli
- Integration (%50-60): Component + state + DOM etkileşimi — React Testing Library bölgesi
- E2E (%5-10): Cypress veya Playwright ile kritik kullanıcı akışları
Bu dağılım sabit değil; SaaS dashboard'u ile e-ticaret sepeti aynı oranlarda test edilmez. Önemli olan, "hızlı geri bildirim" ile "gerçek davranış doğrulaması" arasındaki dengeyi konuya göre ayarlamak.
2. React Testing Library Neden Standart Oldu
RTL'nin yükselişi tesadüf değil. Enzyme component'in iç state'ine erişip setState çağırırken, RTL kullanıcı gibi davranır: getByRole, getByLabelText, userEvent.click. Bu fark, React 18 ile concurrent rendering geldiğinde belirleyici oldu — Enzyme bu API'leri zamanında destekleyemedi ve ekipler hızla göç etti. Daha fazla bilgi için konuya ilişkin kaynaklar başvurulabilir.

"Implementation Detail" Tuzağı
RTL'nin Guiding Principle'ı şu: "Testleriniz yazılıma ne kadar benziyorsa kullanıma, o kadar güven verir." Yani expect(wrapper.state().count).toBe(1) yerine expect(screen.getByText('1 öğe')).toBeInTheDocument(). İlki refactor'da kırılır, ikincisi kullanıcı görene kadar kırılmaz. React temellerini ve component davranışını derinleştirmek isteyenler uygulamalı React eğitimi üzerinden ilerleyebilir.
3. Unit Test: Hook ve Util Katmanı
Bir useDebounce hook'unu RTL'nin renderHook API'si ile test etmek tipik unit senaryosu:
- Saf fonksiyonlar (formatter, validator, reducer) — saniyenin altında çalışır
- Custom hook'lar —
act()ile state güncellemeleri sarmalanır - Context provider'ların initial state üretimi
Burada hız kritiktir. 500 unit testin 3 saniyede koşması beklenir; aksi halde geliştirici testi atlama refleksi geliştirir.
4. Integration: Test Trophy'nin Altın Bölgesi
Bir form component'ini düşünün: input değişir, validation çalışır, submit butonu enable olur, API çağrısı tetiklenir. Bu akışın tek tek unit testi 6-7 dosya gerektirirken, MSW (Mock Service Worker) ile yapılan tek bir integration testi tüm zinciri doğrular ve refactor'a dayanıklıdır.
MSW'nin kritik avantajı: fetch veya axios mock'lamak yerine network katmanını yakaladığı için kütüphane değişikliği teste yansımaz. 2024 itibarıyla npm haftalık indirme sayısı 4 milyonu aştı.
5. E2E: Az ama Doğru
E2E testler pahalı. CI'da 15 dakika koşan bir Cypress suite'i ekibin merge hızını yarıya düşürür. Bu yüzden e2e için seçici olunur:
- Login/signup akışı
- Ödeme veya kritik transactional işlem
- Multi-step wizard veya checkout
- Auth gerektiren protected route geçişleri
Playwright son iki yılda Cypress'in pazar payını ciddi şekilde aşındırdı; State of JS 2023'te Playwright kullanım niyeti %45'e ulaştı, Cypress %39'da kaldı. Sebep: paralel browser, daha hızlı koşum, native mobile emulation.

6. Coverage Metriği Yanıltıcı Olduğunda
%80 coverage hedefi kulağa hoş gelir ama hangi %80 olduğu önemlidir. Try-catch bloklarının happy path'i, log satırları ve getter'lar coverage'ı kolayca şişirir. Onun yerine "kritik kullanıcı akışlarının %100'ü test ediliyor mu?" sorusu daha sağlıklı. RTL'nin screen.debug() ve Testing Playground gibi araçlarına yapılandırılmış bir akış içinde alışmak için React eğitim programı materyalleri yol gösterebilir.
7. Pratik Kurulum Önerisi
- Test runner: Vitest (Vite projeleri için) veya Jest
- Component testi: React Testing Library +
@testing-library/user-eventv14 - Network mock: MSW v2
- E2E: Playwright
- Visual regression: Chromatic veya Percy (opsiyonel ama UI library projelerinde kritik)
Bu yığın, küçük bir startup'tan enterprise ölçekli React uygulamasına kadar ölçeklenir. Önemli olan araç seçimi değil, hangi testin hangi katmanda yaşadığını netleştiren disiplindir. Pyramid mi trophy mi tartışmasından önce, ekibin "biz neyi doğruluyoruz?" sorusunda hemfikir olması gerekir.
Sıkça Sorulan Sorular
Test pyramid mi yoksa Testing Trophy mı React için daha uygun?
İkisi de aynı amaca hizmet ediyor: hızlı geri bildirim ile gerçek davranış doğrulamasını dengelemek. React gibi component tabanlı projelerde Testing Trophy daha gerçekçi çünkü integration testler component render, state ve DOM etkileşimini tek seferde kapsıyor. Saf JavaScript kütüphanelerinde klasik pyramid hâlâ geçerli.
React Testing Library Enzyme'dan neden bu kadar hızlı pay kaptı?
Enzyme component iç state'ine doğrudan erişiyor, bu da refactor'a karşı kırılgan testler üretiyordu. React 18 concurrent rendering geldiğinde Enzyme API'leri zamanında uyumlanamadı. RTL kullanıcı davranışını taklit ettiği için hem React versiyonlarına hem implementation değişikliklerine dayanıklı. State of JS 2023'te RTL kullanımı %84'e ulaştı.
Jest ve Vitest arasında hangisini seçmeliyim?
Create React App veya Next.js projesinde Jest entegrasyonu hazır geliyor. Vite tabanlı projelerde Vitest çok daha hızlı çünkü aynı transform pipeline'ını paylaşıyor ve ESM native çalışıyor. API'leri büyük ölçüde uyumlu, Jest projelerinden Vitest'e geçiş birkaç saatlik bir iş genellikle.
MSW mock kütüphanelerinden ne farkı var?
MSW network katmanını Service Worker veya Node interceptor seviyesinde yakalar. Yani fetch, axios veya başka HTTP istemcisi kullansanız da aynı handler çalışır. Kütüphane değiştirmeniz testlerinizi bozmaz. Ayrıca aynı handler'ları Storybook ve development'ta da kullanabilirsiniz, bu da büyük avantaj.
E2E testleri neden bu kadar az tutmalıyım?
E2E testleri yavaş, kırılgan ve pahalıdır. 15 dakikalık bir suite ekibin merge hızını yarıya düşürür. Asıl maliyet flaky test'lerin yarattığı güven kaybıdır: ekip kırmızı build'leri görmezden gelmeye başlar. Bu yüzden sadece login, ödeme ve kritik akışlar için ayırın, geri kalanı integration katmanında çözün.
Snapshot test ne zaman anlamlıdır?
Snapshot test küçük ve odaklı tutulursa değerli — örneğin bir formatter'ın çıktısı veya küçük bir UI primitive. Tüm component'i snapshot'lamak ise gürültü üretir: her küçük değişiklikte snapshot güncellemek refleks haline gelir, kimse içeriğe bakmaz. Davranış değil çıktı stabilitesi doğrulanıyorsa düşünün.
Coverage %80 yeterli bir hedef mi?
Yüzde değil hangi yüzde olduğu önemli. Try-catch bloklarının happy path'i ve log satırları coverage'ı şişirir ama gerçek değer üretmez. Onun yerine kritik kullanıcı akışlarının ve business logic'in ne kadarının test edildiğini sorgulayın. Mutation testing (Stryker gibi) coverage rakamından çok daha güvenilir bir sinyal verir.
Playwright Cypress'i tamamen geçer mi?
Şu an için yer değiştiriyorlar ama Cypress hâlâ güçlü bir ekosisteme sahip. Playwright'in avantajları paralel browser çalıştırma, native mobile emulation ve daha hızlı koşum. Cypress'in avantajı time-travel debugger ve daha olgun dokümantasyon. Yeni proje başlatıyorsanız Playwright'a yönelin, mevcut Cypress suite'ini taşımak için acil sebep yok.


