07 / 10
API mock
page.route ile istekleri yakalamak, sahte yanıt vermek, gerçek yanıtı değiştirmek, hata ve yükleniyor durumlarını test etmek, glob kalıpları, yanıt beklemek, request fixture'ı ile API testi, HAR dosyaları ve Next.js'te sunucu isteklerinin sınırı.
Neden Mock?
Gerçek sunucu çoğu zaman istediğiniz durumu vermez. Sunucu hatası, boş liste, çok uzun bir müşteri adı ya da yavaş bir yanıt için veritabanını bozmak istemezsiniz. Playwright tarayıcının yaptığı her isteği yakalayıp istediğiniz yanıtı verebilir.1
Playwright dokümanı kontrol etmediğiniz üçüncü parti servisleri test etmemeyi, onların yanıtlarını ağ API'siyle garanti altına almayı da önerir.2 Martin Fowler da uzak servisleri kırılgan testlerin başlıca kaynaklarından sayar ve test dublörleriyle belirli yanıtlar almayı önerir.3
page.route ile Sahte Yanıt
page.route bir URL kalıbı ve bir işleyici alır. route.fulfill isteği sunucuya hiç göndermeden yanıtlar:1
test("boş liste mesajı", async ({ page, ordersPage }) => {
await page.route("**/api/orders?*", (route) => route.fulfill({ json: { orders: [] } }));
await ordersPage.goto();
await expect(ordersPage.empty).toBeVisible();
});Kuralı sayfaya gitmeden önce kurun. Sayfa yüklenirken giden ilk istek de yakalanır.1
json verdiğinizde Content-Type başlığı kendiliğinden eklenir. Hata durumu için status verin:
await page.route("**/api/orders?*", (route) =>
route.fulfill({ status: 500, json: { error: "Sunucu hatası" } }),
);Hata ve Tekrar Deneme
Bu rehberin projesindeki sipariş listesi TanStack Query ile yüklenir; hata olunca "Siparişler yüklenemedi." ve "Tekrar dene" butonu gösterir. Testte önce hatayı üretir, sonra kuralı kaldırıp butona basarsınız:
test("sunucu hatasında hata durumu ve tekrar deneme", async ({ page, ordersPage }) => {
await page.route("**/api/orders?*", (route) =>
route.fulfill({ status: 500, json: { error: "Sunucu hatası" } }),
);
await ordersPage.goto();
await expect(ordersPage.loadError).toBeVisible();
await page.unroute("**/api/orders?*");
await ordersPage.loadError.getByRole("button", { name: "Tekrar dene" }).click();
await expect(ordersPage.rows).toHaveCount(6);
});İpucu
TanStack Query başarısız bir sorguyu varsayılan olarak 3 kez, artan aralıklarla tekrar dener. Hata ekranı birkaç saniye sonra görünür ve 5 saniyelik assertion süresini aşabilir. Projede QueryClient için retry: 1 ayarlıdır (bkz. TanStack Query). Testi geçirmek için uygulamadaki tekrar denemeyi kapatmayın; ayarın gerçek kullanıcıya uygun olup olmadığına bakın.
Gerçek Yanıtı Değiştirmek
Bazen yanıtın çoğu gerçek kalsın, tek bir alan değişsin istersiniz. route.fetch isteği gerçekten yapar; yanıtı değiştirip fulfill ile verirsiniz:1
test("uzun müşteri adı tabloyu bozmaz", async ({ page, ordersPage }) => {
await page.route("**/api/orders?*", async (route) => {
const response = await route.fetch();
const { orders } = await response.json();
orders[0].customer = "Ayşe Nur Yılmaz Karadeniz Uzunsoyadlı";
await route.fulfill({ response, json: { orders } });
});
await ordersPage.goto();
await expect(ordersPage.row("SP-1001")).toContainText("Uzunsoyadlı");
});response'u vermek durum kodunu ve başlıkları korur; yalnızca gövde değişir.
Yükleniyor Durumu
Yükleniyor ekranı çoğu zaman o kadar kısa sürer ki assertion yakalayamaz. page.waitForTimeout ile gecikme eklemek yerine yanıtı bir sözle (Promise) tutun ve testin kendisi bıraksın:
test("yükleniyor durumu görünür", async ({ page, ordersPage }) => {
let release!: () => void;
const gate = new Promise<void>((resolve) => (release = resolve));
await page.route("**/api/orders?*", async (route) => {
await gate;
await route.continue();
});
await ordersPage.goto();
await expect(ordersPage.loading).toBeVisible();
release();
await expect(ordersPage.rows).toHaveCount(6);
});route.continue() isteği değiştirmeden sunucuya gönderir. Süre yerine olaya bağlı olduğu için test her makinede aynı davranır.
Diğer Eylemler
| Metod | Ne yapar |
|---|---|
route.fulfill() | Sunucuya gitmeden yanıt verir |
route.fetch() | İsteği yapar, yanıtı size verir |
route.continue() | İsteği gönderir; başlık, metod ya da gövdeyi değiştirebilir |
route.abort() | İsteği iptal eder; ağ hatası taklidi |
page.unroute() | Kuralı kaldırır |
Görselleri engelleyerek testi hızlandırmak gibi kurallar da yazılabilir: page.route("**/*.{png,jpg,jpeg}", (route) => route.abort()).4
URL Kalıpları
Glob kalıbı URL'nin tamamına uymalıdır:4
*eğik çizgi dışındaki her şeye uyar,**eğik çizgi dahil her şeye.?herhangi bir karaktere değil, yalnızca soru işaretinin kendisine uyar.{png,jpg}seçeneklerden birine uyar.
"**/api/orders" kalıbı /api/orders?status=all isteğine uymaz; sorgu dizesi de URL'nin parçasıdır. Projede bu yüzden "**/api/orders?*" kullanılır. Karmaşık durumlar için düzenli ifade verin: page.route(/\/api\/orders(\?|$)/, …).
Yanıtı Beklemek ve Doğrulamak
Bir eylemin doğru isteği gönderdiğini doğrulamak için waitForResponse kullanın. Bekleyiciyi eylemden önce başlatın, sonra bekleyin:4
const responsePromise = page.waitForResponse("**/api/orders/SP-1001/cancel");
await ordersPage.cancel("SP-1001");
const response = await responsePromise;
expect(response.status()).toBe(200);Çoğu durumda bunu yapmanız gerekmez. Ekrandaki sonucu doğrulamak (satır "İptal edildi" oldu mu) hem kullanıcının gördüğünü test eder hem de yanıtı dolaylı olarak bekler.
Tarayıcısız API Testi
request fixture'ı tarayıcı açmadan HTTP isteği atar. Yetki kurallarını hızlıca denemek ya da teste veri hazırlamak için idealdir.5
test("oturumsuz istek 401 döner", async ({ request }) => {
const response = await request.get("/api/orders");
expect(response.status()).toBe(401);
});page.request ise sayfanın cookie'lerini paylaşır; oturum açmış kullanıcı adına istek atar (bkz. Auth ve fixture). Playwright 1.63 ile request.get<User>(...) gibi bir tip parametresi json()'ın dönüşünü tipler.6
HAR Dosyaları
Çok sayıda isteği tek tek mock'lamak yerine gerçek trafiği bir HAR dosyasına kaydedip testlerde oradan oynatabilirsiniz. update: true kaydeder, olmadan oynatır:1
await page.routeFromHAR("./hars/orders.har", {
url: "**/api/orders?*",
update: true,
});Kaydı bir kez alın, dosyayı depoya ekleyin, update'i kaldırın. Veri değiştiğinde kaydı yenilemeyi unutmayın.
Next.js'te Sınır: Sunucu İstekleri
page.route yalnızca tarayıcının yaptığı istekleri görür. Bir Server Component'in ya da Server Action'ın sunucuda yaptığı fetch tarayıcıdan geçmez; Playwright onu yakalayamaz.
Bu rehberin projesinde sipariş listesi tarayıcıda, TanStack Query ile yüklendiği için mock'lanabilir. Aynı liste bir Server Component'te çekilseydi seçenekler:
Testleri test verisiyle dolu ayrı bir ortama karşı çalıştırmak.
Dış servisin adresini ortam değişkeniyle bir sahte sunucuya yönlendirmek.
Sunucu tarafı mantığı Vitest ile ayrıca test etmek.
Uyarı
Uygulamanız Mock Service Worker (MSW) gibi bir Service Worker tabanlı mock aracı kullanıyorsa, o araç istekleri devralır ve page.route onları göremez. Playwright dokümanı bu durumda testlerde Playwright'ın kendi yönlendirmesini kullanmayı ya da Service Worker'ları serviceWorkers: "block" ile kapatmayı önerir.4
Kendin Dene
Sipariş listesine 500 döndürün ve hata mesajını doğrulayın.
retryayarını kaldırıp testin ne kadar sürdüğüne bakın.route.fetchile gerçek yanıtı alıp bir siparişin durumunu "Kargoda" yapın. Tablonun buna göre güncellendiğini doğrulayın."**/api/orders"kalıbının neden uymadığını görmek için bir test yazın, sonra"**/api/orders?*"ile düzeltin.requestfixture'ıyla oturumsuz ve izleyici rolüyle iptal isteği atıp durum kodlarını doğrulayın.
Detaylı Öğrenmek İçin
Resmi doküman: Playwright, "Mock APIs"; sahte yanıt, yanıt değiştirme ve HAR.1
Resmi doküman: Playwright, "Network"; istek olayları, URL kalıpları ve Service Worker notu.4
Resmi doküman: Playwright, "API testing";
requestfixture'ı ile tarayıcısız test.5
Kaynaklar
`route.fulfill`, `route.fetch` ile yanıt değiştirme ve `routeFromHAR`.
Üçüncü parti bağımlılıkları test etmemek, yanıtı ağ API'siyle garanti altına almak.
: — 14 Nisan 2011. Uzak servisler, test dublörleri ve kontrat testleri.
`route.abort`, `waitForResponse`, glob kalıpları ve Service Worker'lar.
`request` fixture'ı ve `APIRequestContext`.
İstek metodlarında tipli `json()`.
Son güncelleme tarihi: 22 Ekim 2026
