05 / 12
Sorgular
getBy, queryBy, findBy ve sorgu önceliği.
Temel kural
Elemanları kullanıcının bulduğu gibi bulun. Kullanıcı elemanları rol, label ve metin ile bulur. Kullanıcı state adlarını veya CSS class'larını görmez.
İç yapıya bağlı testler küçük bir refactoring işleminde kırılır. Davranışa bağlı testler kırılmaz.1
Sorgu önceliği
Listede yukarıdaki sorgu, aşağıdakinden daha iyidir. Her zaman ilk uygun sorguyu seçin.
| Sorgu | Ne zaman kullanılır |
|---|---|
getByRole | İlk tercih. Button, heading, link, textbox gibi rolü olan her eleman. |
getByLabelText | <label> ile bağlı form elemanları. |
getByText | Etkileşimsiz metin: <p>, <span>, <div>. |
getByAltText | alt attribute'lu görsel. |
getByTestId | Son çare. Başka hiçbir sorgu çalışmıyorsa. |
Tam sıra şöyledir: getByRole, getByLabelText, getByPlaceholderText, getByText, getByDisplayValue, ardından getByAltText, getByTitle ve en sonda getByTestId.2
Uyarı
getByTestId kullanıcının gördüğü bir şey değildir. Önce yukarıdaki sorguları deneyin.2
getByPlaceholderText: Label yoksa kullanılır. Placeholder, label'ın yerini tutmaz. Önce label ekleyin.3getByDisplayValue: Değeri dolu olan input, select veya textarea için.getByTitle:titleattribute'lu eleman için.titleyardımcı teknoloji kullananlar için sorunludur, çünkü tarayıcı ve ekran okuyucu desteği tutarsızdır.4
Örnek sayfa
Bu adımdaki testler ürün listesini kullanır. Component'in tam kodunu Ürün Listesi projesinde görürsünüz. Liste şu HTML'i üretir:
<section aria-label="Ürünler">
<label htmlFor="product-search">Ürün ara</label>
<input id="product-search" type="search" />
<ul>
<li>
<article aria-labelledby="product-2-title">
<h2 id="product-2-title">Mekanik Klavye</h2>
<p>₺2.199,00</p>
<button type="button">Sepete ekle</button>
</article>
</li>
{/* ... diğer ürünler */}
</ul>
</section>Liste veriyi sonradan yükler. Bu yüzden her testin ilk satırı await screen.findAllByRole("article") olur. Bekleme konusunu Asenkron Testler adımında öğrenirsiniz.
import { render, screen } from "@testing-library/react";
import { ProductList } from "./ProductList";
const products = [
{ id: 1, name: "Kablosuz Kulaklık", price: 1299, inStock: true },
{ id: 2, name: "Mekanik Klavye", price: 2199, inStock: true },
{ id: 3, name: "Oyuncu Faresi", price: 899, inStock: false },
];
async function renderList() {
render(
<ProductList
loadProducts={() => Promise.resolve(products)}
onAddToCart={vi.fn()}
/>,
);
await screen.findAllByRole("article");
}
test("ürünü rol, label ve metin ile bulur", async () => {
await renderList();
expect(
screen.getByRole("heading", { name: "Mekanik Klavye" }),
).toBeInTheDocument();
expect(screen.getByLabelText("Ürün ara")).toBeInTheDocument();
expect(screen.getByText("₺2.199,00")).toBeInTheDocument();
});getByRole kullanımı
getByRole, elemanın ARIA rolünü ve erişilebilir adını kullanır. HTML elemanları otomatik bir role sahiptir.56
| HTML | Rol |
|---|---|
<button> | button |
<a href> | link |
<h1> – <h6> | heading |
<input type="search"> | searchbox |
<input type="checkbox"> | checkbox |
<select> | combobox |
<ul> / <li> | list / listitem |
<article aria-labelledby> | article |
<section aria-label> | region |
name seçeneği erişilebilir adı belirtir. Aynı roldeki elemanları ayırmak için bunu kullanın:5
screen.getByRole("button", { name: "Sepete ekle" });
screen.getByRole("heading", { name: "Mekanik Klavye", level: 2 });
screen.getByRole("article", { name: "Mekanik Klavye" });
screen.getByRole("region", { name: "Ürünler" });getByRole, erişilebilirlik ağacından çıkarılan elemanları (hidden, display: none, visibility: hidden, aria-hidden="true") varsayılan olarak yoksayar. Bu elemanları bulmak için hidden: true ekleyin.5
İpucu
Gizli bir elemanın içerikten gelen adı boş hesaplanabilir. Bu durumda hidden: true ile birlikte name kullanırsanız eşleşme olmaz. Gizli eleman için name olmadan sorgulayın veya aria-label ile ad verin.
Sorgu ailesi
Her sorgunun üç ön eki vardır. Ön ek, elemanın şu anda DOM'da olup olmadığını belirler.2
| Ön ek | Eleman bulunamazsa | Ne zaman kullanılır |
|---|---|---|
| getBy* | Hata fırlatır | Eleman şu anda DOM'da olmalı. |
| queryBy* | null döner | Eleman şu anda DOM'da olmamalı. |
| findBy* | Bekler. Süre dolarsa hata fırlatır. | Eleman bir süre sonra gelecek. |
Birden fazla eleman bekliyorsanız All sürümünü kullanın: getAllBy, queryAllBy, findAllBy. Tekil sorgular birden fazla eşleşmede hata fırlatır.
test("sorgu ailesi", async () => {
await renderList();
expect(screen.getAllByRole("article")).toHaveLength(3);
expect(screen.queryByText("Ürün bulunamadı.")).not.toBeInTheDocument();
});Hata
Elemanın yokluğunu kontrol ederken getBy kullanmayın. Eleman yoksa getBy hata fırlatır ve not.toBeInTheDocument satırına hiç ulaşılmaz. Bu durumda queryBy kullanın.
Metin eşleştirme
Metin sorguları varsayılan olarak tam eşleşme ve büyük/küçük harf duyarlı çalışır.27
| Kod | Sonuç |
|---|---|
getByText("Mekanik Klavye") | Yalnızca tam olarak bu metni bulur. |
getByText("klavye") | Bulamaz. Eşleşme tam değil. |
getByText(/klavye/i) | Bulur. Regex kısmi ve büyük/küçük harf duyarsız eşleşir. |
Metin sık değişiyorsa /sepete ekle/i gibi regex kullanabilirsiniz. Regex büyük/küçük harf farkından doğan kırılmaları azaltır. Çok geniş bir regex ise yanlış elemanı da yakalayabilir. Rol sorgusuyla birlikte kullanıp name ile daraltın.
Alan daraltma: within
Listede üç Sepete ekle butonu vardır. getByRole("button", { name: "Sepete ekle" }) hata verir. Aramayı bir kartla sınırlayın:8
import { screen, within } from "@testing-library/react";
test("klavye kartındaki butonu bulur", async () => {
await renderList();
const card = screen.getByRole("article", { name: "Mekanik Klavye" });
expect(
within(card).getByRole("button", { name: "Sepete ekle" }),
).toBeEnabled();
});Testing Playground
HTML'iniz için en uygun sorguyu bu araç önerir. Aşağıdaki örnek bu dersteki ürün kartıdır. Önizlemede bir elemana tıklayın. Önerilen sorguyu okuyun. Sorguyu değiştirip sonucu görün.
Testing Playground
Kendin dene
Oyuncu Faresi kartını
getByRole("article", ...)ile bulun.withinile kartın içindeki Stokta yok yazısının görünür olduğunu test edin.Mekanik Klavye kartında Stokta yok yazısının bulunmadığını
queryByTextile test edin.
Kaynaklar
Uygulama ayrıntılarına bağlı kırılgan testler ve kullanıcının bulduğu gibi sorgulama.
Sorgu önceliği, `getBy`/`queryBy`/`findBy` farkı ve `exact` varsayılanı.
Placeholder, label'ın yerini tutmaz; genelde `getByLabelText` tercih edilir.
`title` kullanımının yardımcı teknoloji kullananlar için sorunları.
Örtük roller, `name`, `level` ve `hidden` seçenekleri.
`getByRole`'ün erişilebilirlik ağacı ve örtük rollerle çalışması.
Metin eşleştirme, regex kullanımı ve `ignore` seçeneği.
Sorguyu tek bir elemanın içine daraltma.
Son güncelleme tarihi: 14 Ekim 2026
