React Bileşenleri Testing Library ile Nasıl Test Edilir: Adım Adım Yöntem
Beceri rehberi

React Bileşenleri Testing Library ile Nasıl Test Edilir: Adım Adım Yöntem

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

React bileşenlerini Testing Library ile kullanıcı gözüyle test edin: render, ByRole sorguları, userEvent, asenkron findBy ve sık hataları örneklerle öğrenin.

Testing Library neye göre test yazar?

React Testing Library'nin temel fikri, bileşeni kullanıcının gördüğü ve yaptığı şeyler üzerinden sınamaktır. Bir state değişkeninin değerine ya da bir iç işlevin çağrılıp çağrılmadığına bakmak yerine, ekranda hangi metnin göründüğünü, hangi düğmenin tıklanabildiğini ve tıklamadan sonra ne olduğunu kontrol edersiniz.

Bu yaklaşımın pratik karşılığı şudur: bileşenin içini yeniden yazsanız bile kullanıcıya görünen davranış aynı kaldığı sürece testler geçmeye devam eder. State'i başka bir hook'a taşımak ya da bir bileşeni ikiye bölmek testi kırmaz. Davranış bozulduğunda ise test kırılır. Test çalıştırıcısı olarak Jest ya da benzeri bir araç, DOM ortamı olarak da bir tarayıcı benzetimi kullanılır; Testing Library bunların üstünde render ve sorgulama araçlarını sağlar.

İlk test: render et, sorgula, doğrula

Her bileşen testi aynı adımları izler: bileşeni çiz, ekrandan öğeyi bul, beklentiyi yaz. Örneğin bir sayaç bileşeni için:

import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import Sayac from "./Sayac";

test("düğmeye basınca sayaç artar", async () => { const user = userEvent.setup(); render(<Sayac />);

await user.click(screen.getByRole("button", { name: /artır/i }));

expect(screen.getByText(/sayaç: bir/i)).toBeInTheDocument(); });

Burada render bileşeni sahte bir DOM'a yerleştirir, screen o DOM'daki öğelere ulaşmanızı sağlar, userEvent ise gerçek bir kullanıcı gibi tıklar. toBeInTheDocument gibi eşleştiriciler jest-dom adlı yardımcı pakettendir ve ayrıca kurulması gerekir.

Test adını davranışı anlatacak biçimde yazın: bileşenin ne yaptığını okuyan biri testin neyi güvence altına aldığını anlamalıdır.

Doğru sorguyu seçmek: ByRole önce gelir

Testing Library dokümantasyonu sorgular için bir öncelik sırası önerir. Herkesin erişebildiği sorgular başta gelir: ByRole, ByLabelText, ByPlaceholderText, ByText ve ByDisplayValue. Ardından anlamsal sorgular gelir: ByAltText ve ByTitle. Sıranın sonunda ByTestId bulunur ve yalnızca başka çare yokken kullanılır.

Bu sıranın nedeni, ilk sorguların yardımcı teknolojilerin sayfayı algıladığı biçime yakın olmasıdır. ByRole ile bir düğmeyi bulabiliyorsanız hem erişilebilirliğin temel koşulunu sınamış olursunuz hem de testi arayüzün görsel sınıf adlarından bağımsız tutarsınız. Formlarda alanı ByLabelText ile bulmak, etiketin gerçekten alana bağlı olduğunu da doğrular.

  • getBy: öğe varsa döner, yoksa ya da birden fazlaysa hata fırlatır.
  • queryBy: öğe yoksa null döner. Bir şeyin ekranda olmadığını doğrularken kullanılır.
  • findBy: öğe görünene kadar bekleyen bir söz döner. Asenkron görünen içerik için kullanılır.
  • Birden fazla öğe beklendiğinde getAllBy, queryAllBy ve findAllBy ailesi kullanılır.

Role göre ararken name seçeneğiyle erişilebilir adı vermek, aynı sayfadaki benzer düğmeleri ayırmanın standart yoludur.

Kullanıcı etkileşimi: userEvent ve fireEvent

Etkileşim için farklı araçlar vardır. fireEvent, tarayıcının olay gönderme mekanizmasını saran ince bir katmandır ve tek bir olayı doğrudan tetikler. userEvent ise gerçek bir kullanıcının yaptığına daha yakın bir dizi olayı çalıştırır ve bazı denetimleri de yapar; örneğin gizli bir öğeye tıklamaz, devre dışı bir alana yazmaz.

Dokümantasyon, userEvent.setup()'ın bileşen çizilmeden önce çağrılmasını önerir. Dönen user nesnesinin yöntemleri söz döndürür, bu yüzden await ile kullanılır.

const user = userEvent.setup(); render(<GirisFormu />);

await user.type(screen.getByLabelText(/e-posta/i), "[email protected]"); await user.click(screen.getByRole("button", { name: /giriş yap/i }));

Çoğu durumda userEvent tercih edilmelidir, çünkü kullanıcıyı daha doğru taklit eder. fireEvent, karşılığı olmayan tarayıcı olaylarını elle tetiklemek gerektiğinde kalır.

Asenkron davranışı sınamak

Veri yükleyen bileşenlerde içerik test başladığı anda ekranda değildir. Bu durumda getBy hemen hata verir. Doğru araç findBy'dır: öğe belirene kadar yeniden dener ve varsayılan zaman aşımı dolarsa reddedilir.

test("siparişler yüklenince listelenir", async () => { render(<SiparisListesi />);

expect(screen.getByText(/yükleniyor/i)).toBeInTheDocument(); expect(await screen.findByText(/sipariş listesi hazır/i)).toBeInTheDocument(); expect(screen.queryByText(/yükleniyor/i)).not.toBeInTheDocument(); });

Ağ isteklerini gerçek sunucuya göndermeyin. İstek katmanını test içinde sahte bir yanıtla değiştirin ya da bir istek yakalayıcı kullanın; testin tekrarlanabilir olması buna bağlıdır. Hata durumunu da ayrı bir test olarak yazın: sunucu hata döndürdüğünde kullanıcıya anlaşılır bir mesaj gösteriliyor mu?

Zamanlayıcılarla çalışan bileşenlerde sahte zamanlayıcıları kullanın ve test sonunda gerçek zamanlayıcıları geri yükleyin. Aksi hâlde testler birbirini etkiler.

Neyi test etmemeli?

En yaygın hata, uygulama ayrıntılarını sınamaktır. Bileşenin iç state'ini okumak, bir hook'un çağrılıp çağrılmadığını saymak ya da sınıf adına göre öğe aramak testleri kırılgan yapar. Kullanıcı bunları görmez; yeniden düzenleme sırasında da davranış aynı kalsa bile testler kırılır.

Bir bileşenin her ayrıntısını tek testte doğrulamaya çalışmak da zararlıdır. Başarısız olan testin neyin bozulduğunu söylemesi gerekir. Küçük, tek davranışa odaklı testler hata ayıklamayı hızlandırır.

  • Üçüncü taraf kütüphanenin kendi içindeki davranışı test etmeyin, onun kendi testleri vardır.
  • Her stil değişikliği için anlık görüntü testi yazmayın. Büyük anlık görüntüler gözden geçirilmez ve körü körüne güncellenir.
  • Testleri bileşen yerine kullanıcı akışı etrafında kurun: formu doldur, gönder, başarı mesajını gör.
  • Sağlayıcı gerektiren bileşenler için tekrar eden sarmalayıcıyı ortak bir yardımcı render işlevinde toplayın.

Bileşen testi nereye oturur?

Bileşen testi, tek tek işlevleri sınayan birim testleri ile tüm uygulamayı gerçek tarayıcıda gezen uçtan uca testler arasındadır. Hızlıdır, çünkü gerçek tarayıcı açmaz; yine de birden fazla alt bileşeni bir arada çizdiği için arayüzün birleşimini sınar.

Pratik bir dağılım şöyledir: saf hesaplamalar için birim testleri, bileşenlerin davranışı için Testing Library, kritik kullanıcı yolculukları için az sayıda uçtan uca test. Testler sürekli entegrasyon hattında her değişiklikte çalıştığında, bileşen testi bozulmayı en erken yakalayan katman hâline gelir.

Mindset programlarında nerede çalışılır?

Modern Web Geliştirme, Frontend (React) eğitiminin Test ve Kalite Güvencesi modülü, React uygulamalarında testi geliştirme akışının parçası yapmak isteyen ön yüz ekipleri içindir. Web Bileşen Test Stratejileri (Component Testing) eğitimi ise Test Katmanları ve Bileşen Testinin Yeri, Sorgulama ve Etkileşim Testleri, İzolasyon ve Asenkron Davranış ile Görsel Doğrulama ve Sürekli Entegrasyon başlıklarıyla konuyu ayrıntılandırır.

Test yazma alışkanlığı olmayan ya da testleri sık sık kıran ekipler için, sorgu seçimi ve asenkron davranış gibi tekrar eden sorunların ortak bir yöntemle çözülmesi açısından uygundur.

İlgili Mindset programı

Modern Web Geliştirme — Frontend (React)

Sık sorulanlar

Sık sorulan sorular

Testing Library ile Jest aynı şey mi?

Hayır. Jest bir test çalıştırıcısıdır: testleri bulur, çalıştırır, sonuç raporlar ve eşleştirici sağlar. Testing Library ise bileşeni çizmeye ve DOM'u kullanıcı gözüyle sorgulamaya yarar. İkisi birlikte kullanılır; Testing Library başka çalıştırıcılarla da çalışabilir, dolayısıyla bağımlı değildir.

getBy, queryBy ve findBy arasındaki fark nedir?

getBy öğe yoksa hata fırlatır, bu yüzden varlığını beklediğiniz öğeler içindir. queryBy öğe yoksa null döner, ekranda olmaması gereken şeyleri doğrulamak için uygundur. findBy ise öğe görünene kadar bekleyen bir söz döner; veri yükleme gibi asenkron durumlarda kullanılır.

data-testid kullanmak yanlış mı?

Yanlış değil ama son çaredir. Dokümantasyonun önerdiği sırada ByTestId en sonda yer alır; önce rol, etiket ve metin gibi kullanıcıya görünen özelliklerle öğeyi bulmaya çalışın. Test kimlikleri erişilebilirliği doğrulamaz ve işaretleme değiştiğinde unutulabilir, bu yüzden yalnızca anlamsal bir yol yoksa eklenmelidir.

Hook'ları nasıl test ederim?

En sağlıklı yol, hook'u kullanan gerçek bir bileşeni çizip davranışı ekranda doğrulamaktır. Hook birçok yerde paylaşılıyorsa küçük bir deneme bileşeni yazıp onun üzerinden sınayabilirsiniz. Hook'un iç değişkenlerine bakmak yerine kullanıcıya yansıyan sonucu kontrol etmek, yeniden düzenlemeye dayanıklı testler üretir.

Test yazmaya nereden başlamalıyım?

Önce uygulamanızın en kritik akışını seçin: giriş, sepete ekleme ya da form gönderimi gibi. O akış için bileşen düzeyinde bir test yazıp ByRole sorgusu ve userEvent ile çalıştırın. Çalışır hâle gelince hata durumlarını ekleyin, sonra benzer bileşenlere yayın. Küçük başlayıp sürekli entegrasyonda çalıştırmak alışkanlığı oturtur.

React Testing Library ile Bileşen Testi Nasıl Yazılır