03 / 12
Temeller
İlk test, render, expect ve matcher'lar.
Test yapısı
Bir test üç adımdan oluşur. Bu yapıya Arrange – Act – Assert (AAA) denir. Türkçesi: hazırla – uygula – doğrula.
| Adım | Ne yapılır | Örnek |
|---|---|---|
| Arrange (hazırla) | Component'i hazırla ve render et. | render(<ProductCard ... />) |
| Act (uygula) | Kullanıcı işlemini yap. | await user.click(button) |
| Assert (doğrula) | Sonucu kontrol et. | expect(...).toHaveBeenCalledWith(...) |
Bu adımda ProductCard component'ine bir Sepete ekle butonu ekleyin:
import { formatPrice } from "./format-price";
import type { Product } from "./types";
type ProductCardProps = {
product: Product;
onAddToCart: (product: Product) => void;
};
export function ProductCard({ product, onAddToCart }: ProductCardProps) {
return (
<article>
<h2>{product.name}</h2>
<p>{formatPrice(product.price)}</p>
{product.inStock ? null : <p>Stokta yok</p>}
<button
type="button"
disabled={!product.inStock}
onClick={() => onAddToCart(product)}
>
Sepete ekle
</button>
</article>
);
}Butona tıklanınca onAddToCart fonksiyonunun çağrıldığını test edin:
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { ProductCard } from "./ProductCard";
test("Sepete ekle butonuna tıklayınca ürünü bildirir", async () => {
// Arrange
const user = userEvent.setup();
const product = { id: 1, name: "Kablosuz Kulaklık", price: 1299, inStock: true };
const onAddToCart = vi.fn();
render(<ProductCard product={product} onAddToCart={onAddToCart} />);
// Act
await user.click(screen.getByRole("button", { name: "Sepete ekle" }));
// Assert
expect(onAddToCart).toHaveBeenCalledWith(product);
});Hata
user.click bir Promise döndürür. await yazmazsanız doğrulama tıklama bitmeden çalışır ve test başarısız olur.
test ve describe
testveitaynı işi yapar.1 Birini seçin ve tüm projede onu kullanın.describeaynı component'in testlerini gruplar.
const headphones = { id: 1, name: "Kablosuz Kulaklık", price: 1299, inStock: true };
describe("ProductCard", () => {
test("ürün adını ve fiyatını gösterir", () => {
render(<ProductCard product={headphones} onAddToCart={vi.fn()} />);
expect(
screen.getByRole("heading", { name: "Kablosuz Kulaklık" }),
).toBeInTheDocument();
expect(screen.getByText("₺1.299,00")).toBeInTheDocument();
});
});Test adını davranış olarak yazın. Örnek: "stokta olmayan ürün için butonu devre dışı bırakır". "test 1" gibi adlar kullanmayın.
render ve screen
render, component'i jsdom içindeki document.body alanına çizer. Her testten sonra React Testing Library bu alanı otomatik temizler. Render sonrası elemanlara screen ile erişin.2
screen ile elemanları üç sorgu ailesiyle bulursunuz: getBy*, queryBy* ve findBy*. Aralarındaki farkı Sorgular adımında öğrenirsiniz. Şimdilik üç ön eki tanıyın.
İpucu
Üç ön ek tüm rehberde aynı rengi kullanır. Rozetin üzerine gelince kısa bir hatırlatma görürsünüz. Sayfanın üstündeki anahtarla ipuçlarını kapatabilirsiniz.
En sık kullanılan matcher'lar
expect(değer) ifadesinden sonra bir matcher çağırırsınız. DOM matcher'ları jest-dom'dan,3 genel ve mock matcher'ları Vitest'ten gelir.4 Component testlerinin büyük bölümü şu matcher'larla yazılır:
| Matcher | Ne kontrol eder |
|---|---|
toBeInTheDocument() | Eleman DOM'da var. |
toBeVisible() | Eleman kullanıcıya görünür. display: none ve hidden elemanlar görünür değildir. |
toBeDisabled() / toBeEnabled() | Form elemanı devre dışı / aktif. |
toHaveTextContent("x") | Eleman metni x içerir. |
toHaveValue("x") | Input, select veya textarea değeri x. |
toHaveAttribute("href", "/x") | Eleman bu attribute değerine sahip. |
toBe(x) / toEqual(x) | Genel değer eşitliği. |
toHaveBeenCalledWith(...) | Mock fonksiyon bu argümanlarla çağrıldı. |
İpucu
toBeInTheDocument ile toBeVisible farklıdır. hidden attribute'lu eleman DOM'da vardır ama görünür değildir. Kullanıcının görmesi gereken elemanlar için toBeVisible kullanın.
jest-dom:
toBeChecked(),toHaveFocus(),toHaveClass("x"),toHaveAccessibleName("x"). Tam liste için jest-dom belgesine bakın.3Vitest:
toHaveLength(n),toThrow(),toHaveBeenCalled(),toHaveBeenCalledTimes(n).4
Aynı testi farklı verilerle çalıştırma
Saf fonksiyonlar için test.each kullanın. Her veri satırı ayrı bir test olur:1
import { formatPrice } from "./format-price";
test.each([
[0, "₺0,00"],
[899, "₺899,00"],
[1299, "₺1.299,00"],
[1299.5, "₺1.299,50"],
])("%s için '%s' döndürür", (price, expected) => {
expect(formatPrice(price)).toBe(expected);
});Testleri bağımsız tutun
Her test kendi başına çalışmalıdır. Her testte component'i yeniden render edin. Testler arasında değişken paylaşmayın.
Uyarı
test.only kodunu commit etmeyin. Yerelde diğer testler çalışmaz ve eksik bir sonuca güvenmiş olursunuz. CI ortamında Vitest varsayılan olarak .only için hata verir, ama CI'a kadar gitmeden .only'yi silin.5
beforeEachortak hazırlık için kullanılır. Yalnızca her testte tekrar eden hazırlık için tercih edin. Testin ne yaptığını okurken hazırlığı da görmek istersiniz.test.skip(...)testi atlar.test.todo("...")henüz yazılmamış testi not eder.1
Kendin dene
ProductCard için bir test yazın. Ürün stokta yoksa kullanıcı şunları görmelidir:
Stokta yok yazısı görünür.
Sepete ekle butonu devre dışıdır.
Kaynaklar
`test` ve `it` takma adı, `test.each`, `test.only`, `test.skip`, `test.todo` ve `describe`.
`render` sonucu, `document.body` içine çizim, otomatik temizlik ve `container` uyarısı.
`toBeInTheDocument`, `toBeVisible`, `toBeDisabled`, `toHaveTextContent` ve diğer DOM matcher'ları.
`toBe`, `toEqual`, `toHaveLength`, `toThrow` ve mock matcher'ları.
CI ortamında `.only` varsayılan olarak yasak.
Son güncelleme tarihi: 14 Ekim 2026
