React Uygulamaları için Playwright ile Bileşen Testi Uygulamaları
Yazılım geliştirme sürecinde kalitenin sağlanması, uygulamanın başarısı için kritik öneme sahiptir. Kullanıcı beklentilerini karşılayan, hatasız ve güvenilir uygulamalar oluşturmak, kapsamlı test stratejileri gerektirir. Bu stratejiler genellikle birim testleri (unit tests), entegrasyon testleri (integration tests) ve uçtan uca (end-to-end – E2E) testler gibi farklı seviyelerde uygulanır. Son yıllarda, bu test hiyerarşisine ek olarak “bileşen testi” (component testing) kavramı da büyük önem kazanmıştır. Bileşen testleri, modern ön yüz (frontend) geliştirme yaklaşımlarında, özellikle React gibi bileşen tabanlı kütüphanelerle çalışırken, geliştiricilere önemli avantajlar sunar.
Bu makalede, React uygulamaları için bileşen testlerinin ne olduğunu, neden bu kadar önemli olduğunu ve Playwright gibi güçlü bir tarayıcı otomasyon aracıyla nasıl etkili bir şekilde uygulanabileceğini detaylı bir şekilde inceleyeceğiz. Playwright’ın sunduğu özel bileşen testi özellikleri sayesinde, React bileşenlerinizi gerçek tarayıcı ortamında, izole bir şekilde test ederek geliştirme sürecinizi hızlandırabilir ve uygulamanızın kalitesini artırabilirsiniz.
Bileşen Testi Nedir ve Neden Önemlidir?
Yazılımda bir “bileşen” (component), uygulamanın kullanıcı arayüzünün (UI) küçük, bağımsız ve yeniden kullanılabilir bir parçasıdır. Örneğin, bir Button, Input, Card veya Modal birer bileşen olabilir. Bileşen testleri, bu bağımsız bileşenlerin tek başlarına doğru çalıştığını doğrulamak amacıyla yapılan testlerdir.
Bileşen testleri, diğer test türleri arasında bir köprü görevi görür:
* Birim Testleri: Genellikle tek bir fonksiyonu veya sınıfı test eder, UI etkileşimlerini içermez.
* Entegrasyon Testleri: Birden fazla birimin veya sistemin birbiriyle nasıl çalıştığını test eder.
* Uçtan Uca (E2E) Testler: Uygulamanın tamamını, bir kullanıcının gerçek senaryolarını taklit ederek test eder. Genellikle tarayıcıda çalışır ve tüm sistemin entegrasyonunu kontrol eder.
Bileşen testleri, bu spektrumda bir bileşenin UI ve etkileşim mantığını, ancak uygulamanın tamamına bağımlı olmadan test etmeyi hedefler.
Bileşen Testlerinin Sağladığı Avantajlar:
1. İzolasyon: Her bileşen kendi başına test edildiği için, testler daha az bağımlılığa sahiptir. Bu, hataların yerini tespit etmeyi kolaylaştırır ve testlerin daha güvenilir olmasını sağlar.
2. Hız: Bileşen testleri, E2E testlerine göre çok daha hızlı çalışır çünkü tüm uygulamanın veya bir arka uç (backend) sunucusunun ayağa kalkmasını gerektirmez. Bu, geliştiricilere daha hızlı geri bildirim döngüsü sunar.
3. Geliştirici Geri Bildirimi: Hızlı geri bildirim sayesinde geliştiriciler, kodlarında yaptıkları değişikliklerin bileşen üzerindeki etkilerini anında görebilir ve sorunları erken aşamada çözebilirler.
4. Güvenilirlik: Bileşenler izole bir şekilde test edildiği için, testler daha az “kırılgan” olur. Uygulamanın başka bir yerindeki değişiklikler genellikle bileşen testlerini etkilemez.
5. Yeniden Kullanılabilirlik ve Bakım Kolaylığı: İyi test edilmiş bileşenler, uygulamanın farklı yerlerinde veya gelecekteki projelerde daha güvenle kullanılabilir. Testler, bileşenin beklenen davranışını belgeleyerek bakım sürecini de kolaylaştırır.
6. Kullanıcı Arayüzü Mantığının Testi: Bir bileşenin prop’lara nasıl tepki verdiği, state’ini nasıl yönettiği ve kullanıcı etkileşimlerine nasıl yanıt verdiği gibi UI’a özgü mantıkları doğrudan test etme imkanı sunar.
Playwright Nedir ve Neden Bileşen Testleri İçin Tercih Edilmelidir?
Playwright, Microsoft tarafından geliştirilen modern bir tarayıcı otomasyon kütüphanesidir. Chromium, Firefox ve WebKit gibi tüm modern tarayıcılarda çalışabilme yeteneğiyle öne çıkar. Playwright başlangıçta uçtan uca (E2E) testler için tasarlanmış olsa da, sunduğu güçlü API’ler ve gerçek tarayıcı ortamında çalışma yeteneği sayesinde bileşen testleri için de ideal bir araç haline gelmiştir. Playwright, özellikle React gibi bileşen tabanlı kütüphanelerle çalışırken, bileşenlerinizi gerçek bir tarayıcı ortamında, izole bir şekilde render edip etkileşime geçerek test etme imkanı sunar.
Playwright’ın Bileşen Testi Yaklaşımı:
Playwright’ın bileşen testleri için özel olarak geliştirilmiş @playwright/experimental-ct-react (veya gelecekteki stabil versiyonu) paketi, React bileşenlerini doğrudan bir tarayıcı bağlamında “mount” etme (DOM’a bağlama) yeteneği sağlar. Bu, geleneksel birim test kütüphanelerinin (Jest, Vitest) sunduğu sanal DOM (JSDOM) ortamından farklı olarak, bileşenlerinizin gerçek tarayıcı ortamında (CSS, JavaScript, tarayıcı API’leri dahil) nasıl davrandığını test etmenizi sağlar.
* Gerçek Tarayıcı Ortamı: Bileşenleriniz, stil dosyaları, resimler ve tarayıcıya özgü API’ler dahil olmak üzere tam bir tarayıcı ortamında test edilir. Bu, JSDOM gibi sanal ortamların kaçırabileceği render veya etkileşim sorunlarını yakalamayı sağlar.
* Hız ve Güvenilirlik: Playwright’ın test runner’ı, testleri paralel olarak ve izole bir şekilde çalıştırarak yüksek hız ve güvenilirlik sunar.
* Kapsamlı API: Playwright’ın güçlü seçici (locator) API’leri, kullanıcı etkileşimlerini (tıklama, yazma, sürükleme vb.) simüle etme yetenekleri ve doğrulama (assertion) mekanizmaları, karmaşık bileşen davranışlarını test etmeyi kolaylaştırır.
* Görsel Regresyon Testleri: Bileşenlerin görsel çıktılarının ekran görüntülerini alarak, stil veya düzen değişikliklerinin istenmeyen görsel regresyonlara yol açıp açmadığını otomatik olarak kontrol edebilirsiniz.
* Geliştirme Sunucusu Entegrasyonu: Playwright’ın bileşen testi özelliği, Vite veya Webpack gibi geliştirme sunucularıyla sorunsuz bir şekilde entegre olarak, bileşenlerinizi hızlıca derleyip test ortamına sunar.
Playwright Bileşen Test Ortamının Kurulumu
React uygulamalarınızda Playwright ile bileşen testlerini uygulamak için öncelikle gerekli bağımlılıkları yüklemeniz ve Playwright’ı yapılandırmanız gerekir.
1. Proje Oluşturma veya Mevcut Projeye Ekleme:
Yeni bir React projesi oluşturuyorsanız veya mevcut bir projeye Playwright’ı ekliyorsanız, aşağıdaki adımları izleyebilirsiniz. Playwright, React Component Testing için Vite gibi modern bir bundler ile en iyi şekilde çalışır.
Eğer sıfırdan bir proje oluşturup Playwright’ı eklemek isterseniz, Playwright’ın kendi CLI’ı bunu kolaylaştırır:
# Yeni bir React projesi oluşturun (örneğin Vite ile)
npm create vite@latest my-react-app -- --template react-ts
cd my-react-app
Playwright'ı bileşen testi desteğiyle yükleyin
npm init playwright@latest -- --ct
Bu komut, Playwright’ı yükleyecek, playwright.config.ts dosyasını oluşturacak ve React Component Testing için gerekli bağımlılıkları (örn. @playwright/experimental-ct-react) kuracaktır.
Mevcut bir projeye ekliyorsanız:
npm install -D @playwright/test @playwright/experimental-ct-react react react-dom vite
Eğer TypeScript kullanıyorsanız:
npm install -D @types/react @types/react-dom
Ardından, Playwright yapılandırma dosyasını manuel olarak oluşturmanız gerekebilir.
2. playwright.config.ts Yapılandırması:
Playwright, playwright.config.ts (veya .js) dosyası aracılığıyla yapılandırılır. Bileşen testleri için bu dosyanın özel ayarlara sahip olması gerekir. npm init playwright@latest -- --ct komutu genellikle bu dosyayı otomatik olarak oluşturur. Örnek bir playwright.config.ts dosyası aşağıdaki gibi görünebilir:
import { defineConfig, devices } from '@playwright/experimental-ct-react';
import { resolve } from 'path';
/
* Playwright bileşen testi yapılandırması.
* Daha fazla bilgi için: https://playwright.dev/docs/test-components
*/
export default defineConfig({
testDir: './', // Test dosyalarının aranacağı dizin
testMatch: '/*.spec.{ts,tsx,js,jsx}', // Test dosyası kalıbı
/ Testlerin paralel çalıştırılıp çalıştırılmayacağını yapılandırın. /
fullyParallel: true,
/ Test hatalarında tekrardan deneme sayısını yapılandırın. /
retries: process.env.CI ? 2 : 0,
/ Test raporlarını yapılandırın. /
reporter: 'html',
/ Tarayıcı bağlamı ayarları. /
use: {
/ Test sırasında kullanılacak temel URL. /
// baseURL: 'http://127.0.0.1:3000',
/ Test sırasında kullanılacak viewport boyutu. /
viewport: { width: 1280, height: 720 },
/ Test sırasında tarayıcı konsol çıktılarını yakala. /
trace: 'on-first-retry',
/ Component Testing için gerekli ayarlar. /
ctPort: 3100, // Bileşenlerin sunulacağı port
ctViteConfig: { // Vite özelinde yapılandırma
resolve: {
alias: {
'@/components': resolve(__dirname, './src/components'),
// Diğer alias'lar buraya eklenebilir
},
},
},
// Eğer Webpack kullanıyorsanız ctWebpackConfig ayarını kullanın.
},
/ Projeleri yapılandırın. /
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
Yapılandırmadaki Önemli Noktalar:
* testDir ve testMatch: Playwright’ın test dosyalarınızı nerede bulacağını belirler. Genellikle bileşenlerin yanında (.spec.tsx gibi) tutulur.
* use.ctPort: Bileşenlerinizin geliştirme sunucusu tarafından sunulacağı portu belirtir.
* use.ctViteConfig (veya ctWebpackConfig): Bileşenlerinizi derlemek için kullanılacak Vite (veya Webpack) yapılandırmasını tanımlar. Bu, özellikle path alias (yol takma adları) gibi özel bundler ayarlarınız varsa önemlidir.
* projects: Testlerin farklı tarayıcılarda çalıştırılmasını sağlar.
Basit Bir React Bileşeni Oluşturma
Şimdi, test edeceğimiz basit bir React bileşeni oluşturalım. Bir Counter bileşeni, hem prop alacak hem de state yönetecek basit bir örnek olacaktır.
src/components/Counter.tsx:
import React, { useState } from 'react';
interface CounterProps {
initialValue?: number;
step?: number;
}
const Counter: React.FC = ({ initialValue = 0, step = 1 }) => {
const [count, setCount] = useState(initialValue);
const increment = () => {
setCount(prevCount => prevCount + step);
};
const decrement = () => {
setCount(prevCount => prevCount - step);
};
return (
Count: {count}
);
};
export default Counter;
Bu bileşen, başlangıç değeri ve adım boyutu alabilen, artırma ve azaltma düğmeleri olan basit bir sayacı temsil eder. data-testid öznitelikleri, Playwright seçicileri için hedef belirlemeyi kolaylaştırır.
İlk Bileşen Testini Yazma
Şimdi Counter bileşenimiz için bir test dosyası oluşturalım. Bu dosya genellikle bileşenin yanında veya __tests__ gibi özel bir klasörde bulunur.
src/components/Counter.spec.tsx:
import { test, expect } from '@playwright/experimental-ct-react';
import Counter from './Counter';
test.use({ viewport: { width: 500, height: 500 } }); // Test için özel viewport ayarı
test('should display the initial count', async ({ mount }) => {
const component = await mount( );
await expect(component.getByTestId('counter-value')).toHaveText('Count: 10');
});
test('should increment the count when the increment button is clicked', async ({ mount }) => {
const component = await mount( );
const incrementButton = component.getByTestId('increment-button');
const counterValue = component.getByTestId('counter-value');
await expect(counterValue).toHaveText('Count: 0'); // Başlangıç değeri 0
await incrementButton.click();
await expect(counterValue).toHaveText('Count: 1');
await incrementButton.click();
await expect(counterValue).toHaveText('Count: 2');
});
test('should decrement the count when the decrement button is clicked', async ({ mount }) => {
const component = await mount( );
const decrementButton = component.getByTestId('decrement-button');
const counterValue = component.getByTestId('counter-value');
await expect(counterValue).toHaveText('Count: 5');
await decrementButton.click();
await expect(counterValue).toHaveText('Count: 4');
});
test('should increment/decrement by the specified step', async ({ mount }) => {
const component = await mount( );
const incrementButton = component.getByTestId('increment-button');
const decrementButton = component.getByTestId('decrement-button');
const counterValue = component.getByTestId('counter-value');
await expect(counterValue).toHaveText('Count: 0');
await incrementButton.click();
await expect(counterValue).toHaveText('Count: 5');
await decrementButton.click();
await expect(counterValue).toHaveText('Count: 0');
});
test('should render correctly on different viewports', async ({ mount, page }) => {
const component = await mount( );
await expect(component).toBeVisible();
// Testin kendisi için viewport ayarını override edebiliriz
await page.setViewportSize({ width: 320, height: 480 });
await expect(component).toBeVisible(); // Yine de görünür olmalı
// Görsel regresyon testi burada yapılabilir
// expect(await component.screenshot()).toMatchSnapshot('counter-mobile.png');
});
Test Kodunun Açıklaması:
* import { test, expect } from '@playwright/experimental-ct-react';: Playwright’ın bileşen testi için özel olarak sağladığı test ve expect fonksiyonlarını import ederiz.
* test.use({ viewport: { width: 500, height: 500 } });: Bu, tüm test bloğu için varsayılan bir viewport boyutu ayarlar. Her test kendi içinde bu ayarı geçersiz kılabilir.
* test('...', async ({ mount }) => { ... });: Her test bloğu test fonksiyonu ile tanımlanır. mount fonksiyonu, Playwright’ın bileşeni bir tarayıcı ortamında render etmesini sağlayan ana araçtır.
* const component = await mount(: Counter bileşenini belirli prop’larla mount ederiz. mount fonksiyonu, render edilen bileşeni temsil eden bir Locator döndürür.
* component.getByTestId('counter-value'): Bileşen içindeki belirli bir elementi data-testid özniteliği ile buluruz. Playwright, metin, rol, etiket adı gibi birçok farklı seçici türünü destekler.
* await expect(locator).toHaveText('...');: Bulunan elementin beklenen metin içeriğine sahip olup olmadığını doğrularız.
* await incrementButton.click();: Düğmeye tıklama gibi kullanıcı etkileşimlerini simüle ederiz. Playwright, fill, press, hover gibi birçok etkileşim metoduna sahiptir.
Gelişmiş Bileşen Testi Teknikleri
Basit bir bileşenin ötesine geçerek, Playwright ile daha karmaşık senaryoları nasıl test edebileceğimize bakalım.
Prop ve State Yönetimi
Bileşenler genellikle karmaşık prop yapılarına ve dahili state’lere sahiptir. Playwright’ın mount fonksiyonu, farklı prop kombinasyonlarıyla bileşenleri kolayca test etmenizi sağlar.
// Karmaşık prop'lara sahip bir UserProfile bileşeni
interface User {
id: string;
name: string;
email: string;
isAdmin: boolean;
}
interface UserProfileProps {
user: User;
onEdit: (user: User) => void;
onDelete: (userId: string) => void;
}
// UserProfile.tsx (örnek)
// ...
// UserProfile.spec.tsx
test('should display user details correctly for an admin user', async ({ mount }) => {
const adminUser: User = {
id: '1',
name: 'Alice Admin',
email: 'alice@example.com',
isAdmin: true,
};
const onEdit = test.fn(); // Playwright'ın mock fonksiyonu
const onDelete = test.fn();
const component = await mount( );
await expect(component.getByText('Alice Admin')).toBeVisible();
await expect(component.getByText('alice@example.com')).toBeVisible();
await expect(component.getByRole('button', { name: 'Edit Profile' })).toBeVisible();
await expect(component.getByRole('button', { name: 'Delete User' })).toBeVisible();
});
test('should not show delete button for non-admin users', async ({ mount }) => {
const normalUser: User = {
id: '2',
name: 'Bob User',
email: 'bob@example.com',
isAdmin: false,
};
const onEdit = test.fn();
const onDelete = test.fn();
const component = await mount( );
await expect(component.getByRole('button', { name: 'Delete User' })).not.toBeVisible();
});
test('should call onEdit when edit button is clicked', async ({ mount }) => {
const user: User = { id: '1', name: 'Alice', email: 'a@e.com', isAdmin: false };
const onEdit = test.fn();
const onDelete = test.fn();
const component = await mount( );
await component.getByRole('button', { name: 'Edit Profile' }).click();
expect(onEdit).toHaveBeenCalledWith(user); // onEdit fonksiyonunun doğru argümanla çağrıldığını doğrula
});
Olay Tetikleme ve Asenkron Etkileşimler
Kullanıcı etkileşimleri ve asenkron işlemler (örneğin, API çağrıları sonrası state güncellemeleri) Playwright ile kolayca test edilebilir.
// LoginForm.tsx (örnek)
// Bir onSubmit prop'u alan ve kullanıcı girişi yapan bir form.
// ...
// LoginForm.spec.tsx
test('should submit form with correct credentials', async ({ mount }) => {
const onSubmit = test.fn();
const component = await mount( );
await component.getByLabel('Username').fill('testuser');
await component.getByLabel('Password').fill('password123');
await component.getByRole('button', { name: 'Login' }).click();
expect(onSubmit).toHaveBeenCalledWith({ username: 'testuser', password: 'password123' });
});
// Asenkron bir işlem sonrası yükleme durumunu test etme
test('should show loading spinner during async submission', async ({ mount }) => {
const onSubmit = test.fn(async () => {
await new Promise(resolve => setTimeout(resolve, 100)); // 100ms gecikme
});
const component = await mount( );
await component.getByLabel('Username').fill('testuser');
await component.getByLabel('Password').fill('password123');
await component.getByRole('button', { name: 'Login' }).click();
await expect(component.getByTestId('loading-spinner')).toBeVisible();
await expect(component.getByRole('button', { name: 'Login' })).toBeDisabled();
await onSubmit; // Promise'ın tamamlanmasını bekle
await expect(component.getByTestId('loading-spinner')).not.toBeVisible();
await expect(component.getByRole('button', { name: 'Login' })).toBeEnabled();
});
Mocking ve Stubbing
Bileşenler genellikle harici API’lere, context’lere veya custom hook’lara bağımlıdır. Bu bağımlılıkları Playwright testleri içinde mock’lamak, bileşenleri izole bir şekilde test etmek için kritik öneme sahiptir.
API Çağrılarını Mocklama (page.route()):
// UserList.tsx (örnek)
// API'den kullanıcı listesi çeken bir bileşen
// ...
// UserList.spec.tsx
test('should display a list of users fetched from API', async ({ mount, page }) => {
// API çağrısını mock'la
await page.route('/api/users', route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([
{ id: '1', name: 'Alice' },
{ id: '2', name: 'Bob' },
]),
});
});
const component = await mount( );
await expect(component.getByText('Alice')).toBeVisible();
await expect(component.getByText('Bob')).toBeVisible();
});
Context API veya Custom Hook’ları Mocklama:
Playwright’ın mount fonksiyonu, bir bileşeni render ederken kendi Provider‘larınızı veya mock’lanmış hook’larınızı sarmalamanıza izin verir.
// ThemeContext.tsx (örnek)
// Bir tema sağlayan Context
// ...
// ThemedButton.tsx (örnek)
// ThemeContext'ten tema kullanan bir düğme
// ...
// ThemedButton.spec.tsx
import { test, expect } from '@playwright/experimental-ct-react';
import { ThemeProvider } from '../contexts/ThemeContext'; // Gerçek Context Provider
import ThemedButton from './ThemedButton';
test('should render button with light theme', async ({ mount }) => {
const component = await mount(
{} }}>
);
await expect(component.locator('button')).toHaveCSS('background-color', 'rgb(255, 255, 255)'); // Beyaz arkaplan
});
test('should render button with dark theme', async ({ mount }) => {
const component = await mount(
{} }}>
);
await expect(component.locator('button')).toHaveCSS('background-color', 'rgb(0, 0, 0)'); // Siyah arkaplan
});
Görsel Regresyon Testleri
Playwright, bileşenlerin görsel çıktılarının ekran görüntülerini alarak, UI değişikliklerinin beklenmeyen görsel bozulmalara yol açıp açmadığını kontrol etmenizi sağlar.
test('should match snapshot of the counter component', async ({ mount }) => {
const component = await mount( );
await expect(component).toHaveScreenshot('counter-initial.png');
});
test('should match snapshot after incrementing', async ({ mount }) => {
const component = await mount( );
await component.getByTestId('increment-button').click();
await expect(component).toHaveScreenshot('counter-incremented.png');
});
toHaveScreenshot ilk çalıştırıldığında bir referans ekran görüntüsü oluşturur. Sonraki çalıştırmalarda, mevcut ekran görüntüsü referansla karşılaştırılır. Herhangi bir fark bulunursa test başarısız olur ve farkları gösteren bir rapor oluşturulur.
Erişilebilirlik (Accessibility) Testleri
Playwright, axe-playwright gibi kütüphanelerle entegre olarak bileşenlerinizin erişilebilirlik standartlarına uygunluğunu otomatik olarak kontrol etmenize olanak tanır.
npm install -D axe-playwright
import { test, expect } from '@playwright/experimental-ct-react';
import { injectAxe, checkA11y } from 'axe-playwright';
import Counter from './Counter';
test('Counter component should be accessible', async ({ mount, page }) => {
await mount( );
await injectAxe(page); // Axe kütüphanesini sayfaya enjekte et
await checkA11y(page, null, {
// Kuralları özelleştirebilirsiniz
detailedReport: true,
detailedReportOptions: { html: true },
});
});
Bu test, Counter bileşeninin WCAG (Web Content Accessibility Guidelines) standartlarına uygun olup olmadığını kontrol eder ve herhangi bir ihlal durumunda test başarısız olur.
Testleri Çalıştırma ve Raporlama
Playwright testlerinizi çalıştırmak ve sonuçları raporlamak oldukça basittir.
1. Testleri Çalıştırma:
Tüm bileşen testlerini çalıştırmak için:
npx playwright test --project=component
--project=component parametresi, playwright.config.ts dosyasında tanımlanan bileşen test projesini hedef alır. Eğer varsayılan olarak tüm projeleri çalıştırmak isterseniz sadece npx playwright test de kullanabilirsiniz.
Belirli bir test dosyasını çalıştırmak için:
npx playwright test src/components/Counter.spec.tsx
Belirli bir test bloğunu veya testi çalıştırmak için --grep veya --grep-invert kullanabilirsiniz:
npx playwright test --grep "initial count"
2. UI Modu:
Playwright’ın UI modu, testlerinizi görsel olarak çalıştırmanıza, hata ayıklamanıza ve adım adım ilerlemenize olanak tanır.
npx playwright test --ui
Bu, tarayıcıda Playwright Test Runner UI’ını açar. Burada testleri tek tek veya toplu olarak çalıştırabilir, adımları görebilir, DOM’u inceleyebilir ve ekran görüntülerini karşılaştırabilirsiniz.
3. HTML Raporu:
Testler tamamlandıktan sonra, Playwright otomatik olarak kapsamlı bir HTML raporu oluşturur.
npx playwright show-report
Bu komut, tarayıcınızda playwright-report klasöründeki HTML raporunu açar. Rapor, geçen, başarısız olan veya atlanan testleri, test sürelerini, hata mesajlarını, ekran görüntülerini ve videoları (yapılandırılmışsa) gösterir.
4. CI/CD Entegrasyonu:
Playwright testleri, GitHub Actions, GitLab CI, Jenkins gibi sürekli entegrasyon/sürekli dağıtım (CI/CD) pipeline’larına kolayca entegre edilebilir. Genellikle, npx playwright test komutu CI ortamında çalıştırılır ve --reporter=github veya --reporter=json gibi farklı raporlama seçenekleri kullanılır.
# Örnek GitHub Actions iş akışı
name: Playwright Component Tests
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test --project=component
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
En İyi Uygulamalar ve İpuçları
Playwright ile bileşen testlerini yazarken verimliliği ve test kalitesini artırmak için bazı en iyi uygulamalar şunlardır:
1. İzolasyonu Koruyun: Her test, test ettiği bileşenin tek bir yönüne odaklanmalı ve diğer bileşenlerden veya dış bağımlılıklardan izole olmalıdır. Mocklama tekniklerini kullanarak bu izolasyonu sağlayın.
2. Anlamlı Seçiciler Kullanın: data-testid öznitelikleri, testlerinizin UI değişikliklerinden daha az etkilenmesini sağlar. getByRole, getByText, getByLabel gibi Playwright’ın kullanıcıya yönelik seçicilerini tercih edin. CSS seçicileri (.my-class) veya XPath, genellikle daha kırılgan olabilir.
3. Açıklayıcı Test İsimleri: Test fonksiyonlarınıza neyi test ettiklerini açıkça belirten isimler verin. “should display initial count” gibi.
4. Arrange-Act-Assert (AAA) Prensibi: Her testinizi üç aşamaya ayırın:
* Arrange (Hazırlık): Test ortamını ve bileşeni kurun (mount edin, prop’ları ayarlayın).
* Act (Eylem): Bileşenle etkileşime geçin (tıklayın, yazın).
* Assert (Doğrulama): Bileşenin beklenen şekilde davrandığını doğrulayın.
5. Duyarlı Testler: Bileşenlerinizin farklı ekran boyutlarında nasıl davrandığını test etmek için test.use({ viewport: { width, height } }) ile farklı viewport boyutları kullanın.
6. Performans İpuçları:
* Testleri paralel çalıştırmak için fullyParallel: true ayarını kullanın.
* Gereksiz yere page.pause() veya page.waitForTimeout() kullanmaktan kaçının. Playwright’ın otomatik bekleme mekanizmaları genellikle yeterlidir.
* Headless modda çalıştırın (playwright.config.ts içinde headless: true varsayılan olarak gelir).
7. Test Verilerini Yönetme (Fixtures): Karmaşık veya tekrarlayan test verileri için Playwright’ın fixtures özelliğini kullanabilirsiniz. Bu, test kodunuzu daha temiz ve yeniden kullanılabilir hale getirir.
Sık Karşılaşılan Sorunlar ve Çözümleri
* Asenkron İşlemlerin Beklenmesi: Playwright, DOM değişikliklerini otomatik olarak beklese de, bazen API çağrıları gibi uzun süreli asenkron işlemlerin tamamlanmasını manuel olarak beklemeniz gerekebilir. await page.waitForSelector(), await expect(locator).toBeVisible() veya await expect(locator).toBeEnabled() gibi yöntemler, elementlerin görünür veya etkileşimli olmasını beklemek için etkilidir.
* Seçici Sorunları: Yanlış seçici kullanımı veya elementlerin DOM’a geç yüklenmesi seçici hatalarına yol açabilir. data-testid kullanmak ve Playwright’ın otomatik bekleme özelliklerine güvenmek bu sorunları azaltır. Gerekirse page.locator('selector', { hasText: '...' }) gibi daha spesifik seçiciler kullanın.
* Yapılandırma Hataları: playwright.config.ts dosyasındaki yanlış testMatch, ctViteConfig veya ctPort ayarları testlerin çalışmamasına neden olabilir. Konsol çıktılarını dikkatlice inceleyin. Özellikle ctViteConfig içindeki alias ayarlarının projenizin vite.config.ts dosyasıyla eşleştiğinden emin olun.
* CSS/Stil Yükleme Sorunları: Bazen bileşen testleri sırasında CSS dosyaları doğru şekilde yüklenmeyebilir ve bu da görsel testlerde veya stil tabanlı kontrollerde sorunlara yol açabilir. playwright.config.ts içindeki ctViteConfig veya ctWebpackConfig ayarlarınızın, projenizin stil yükleme kurallarını (CSS modülleri, PostCSS, Sass vb.) doğru şekilde yansıttığından emin olun.
Sonuç
React uygulamaları için Playwright ile bileşen testi, modern ön yüz geliştirme süreçlerinin ayrılmaz bir parçasıdır. Playwright’ın gerçek tarayıcı ortamında bileşenleri izole bir şekilde test etme yeteneği, geliştiricilere hızlı geri bildirim, yüksek güvenilirlik ve kapsamlı test kapsamı sağlar. Bu yaklaşım, birim testlerinin sınırlamalarını aşarken, E2E testlerinin yavaşlığını ve kırılganlığını azaltır.
Playwright’ın @playwright/experimental-ct-react paketi ve güçlü API’leri sayesinde, React bileşenlerinizin prop’lara nasıl tepki verdiğini, state’i nasıl yönettiğini, kullanıcı etkileşimlerine nasıl yanıt verdiğini ve hatta görsel olarak nasıl göründüğünü detaylı bir şekilde test edebilirsiniz. Mocklama, erişilebilirlik kontrolleri ve görsel regresyon testleri gibi gelişmiş tekniklerle birleştiğinde, Playwright ile bileşen testleri, React uygulamalarınızın kalitesini ve sürdürülebilirliğini önemli ölçüde artırır.
Geliştirme sürecinize Playwright ile bileşen testlerini entegre etmek, daha az hata içeren, daha stabil ve kullanıcı beklentilerini karşılayan React uygulamaları oluşturmanıza yardımcı olacaktır. Bu yatırım, uzun vadede hem geliştirici verimliliğini artıracak hem de son kullanıcının memnuniyetini sağlayacaktır.