GitHub Actions ve Playwright Sharding ile CI/CD
Büyük test paketlerinizin CI/CD süreçlerini yavaşlatmasından sıkıldınız mı? GitHub Actions ve Playwright Sharding ile test sürelerinizi nasıl dakikalara indireceğinizi keşfedin.
Modern yazılım geliştirme süreçlerinde hız ve güvenilirlik her şeyden önce gelir. Geliştiriciler yazdıkları kodların doğruluğundan emin olmak isterken, aynı zamanda bu kontrol süreçlerinin saatler sürmesini istemezler. Projeler büyüdükçe, yazılan uçtan uca (E2E – End-to-End) testlerin sayısı da kaçınılmaz olarak artar. Başlangıçta birkaç dakika süren test süreçleri, zamanla geliştirme ekiplerinin önünde büyük bir engel haline gelebilir. İşte tam bu noktada devreye modern test otomasyon araçları ve akıllı CI/CD (Continuous Integration / Continuous Deployment – Sürekli Entegrasyon / Sürekli Dağıtım) stratejileri giriyor.
Bu makalede, Playwright ve TypeScript kullanarak hazırladığınız test paketlerini, GitHub Actions üzerinde “Sharding” (parçalara ayırma) yöntemiyle nasıl paralel olarak çalıştıracağınızı adım adım inceleyeceğiz. Bu sayede test sürelerinizi nasıl radikal bir şekilde düşürebileceğinizi gerçek dünya senaryolarıyla göreceksiniz.
Test Sürelerini Kısaltmanın Sırrı: Sharding Nedir?
Yazılım test süreçlerinde karşılaşılan en büyük zorluklardan biri, testlerin doğrusal bir şekilde, yani ardı ardına çalıştırılmasıdır. Yüzlerce test senaryosunun tek bir makinede sırayla çalışması, özellikle karmaşık kullanıcı etkileşimleri içeren web uygulamalarında saatler sürebilir. Bu sorunu çözmek için geleneksel yöntemlerde yerel makinelerin işlemci çekirdeklerinden yararlanarak paralel çalıştırma (multithreading) yoluna gidilir. Ancak tek bir sunucunun veya sanal makinenin gücü de bir yere kadar yeterlidir.
Sharding (parçalara ayırma), test paketinizi mantıksal veya fiziksel olarak daha küçük parçalara bölüp, bu parçaları tamamen bağımsız farklı makinelerde (runner) eş zamanlı olarak çalıştırma işlemidir. Playwright, sunduğu yerleşik sharding desteği sayesinde bu süreci inanılmaz derecede kolaylaştırır. Örneğin, 100 adet testten oluşan bir paketiniz olduğunu düşünelim. Bu testleri tek bir makinede çalıştırmak yerine, her biri 25 test içeren 4 farklı gruba (shard) ayırabilir ve bunları GitHub Actions üzerinde aynı anda çalışan 4 farklı sanal makineye dağıtabilirsiniz.
Bu yaklaşım, teorik olarak test sürenizi yaklaşık dörtte birine indirir. Playwright, hangi testin hangi parçaya gideceğini otomatik olarak hesaplar. Bu sayede sizin test dosyalarını manuel olarak bölmenize gerek kalmaz. Aşağıdaki tabloda, geleneksel sıralı test yaklaşımı ile sharding yaklaşımı arasındaki temel farkları inceleyebilirsiniz:
| Metrik | Geleneksel Sıralı Test | Playwright Sharding (4 Shard) |
|---|---|---|
| Çalışma Süresi | Çok Yüksek (Örn: 40 dakika) | Düşük (Örn: 10 dakika) |
| Kaynak Kullanımı | Tek Makine (Sınırlı kaynak) | Dağıtık Yapı (Yüksek kaynak) |
| Maliyet Yapısı | Düşük (Tek makine süresi) | Orta (Paralel çalışan makine süresi) |
| Hata Analizi | Zor (Tek büyük rapor dosyası) | Kolay (Birleştirilmiş tek rapor) |
GitHub Actions Üzerinde Playwright Altyapısı Nasıl Kurulur?
GitHub Actions üzerinde Playwright testlerini koşturmak için öncelikle projenizin kök dizininde bir iş akışı (workflow) dosyası tanımlamanız gerekir. Bu dosya, GitHub platformuna testlerinizin hangi tetikleyicilerle (trigger), hangi işletim sisteminde ve hangi bağımlılıklarla çalışacağını söyler. TypeScript tabanlı bir Playwright projesinde ilk adım, temiz bir iş akışı dosyası oluşturmaktır.
Öncelikle projenizin ana dizininde .github/workflows klasör yapısını oluşturun ve içerisine playwright.yml adında bir dosya ekleyin. Bu dosya, CI/CD hattımızın kalbi olacaktır. İlk aşamada, sharding yapmadan önce temel bir GitHub Actions iş akışının nasıl görünmesi gerektiğine bakalım. Bu sayede temel yapıyı anlayıp, üzerine sharding mimarisini inşa etmemiz çok daha kolay olacaktır.
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
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
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
Yukarıdaki yapılandırma, her kod gönderiminde (push) veya çekme isteğinde (pull request) tetiklenir. Temel olarak Ubuntu işletim sistemini ayağa kaldırır, Node.js ortamını kurar, projenin bağımlılıklarını yükler, gerekli tarayıcı motorlarını indirir ve testleri çalıştırır. Son olarak da test raporunu bir çıktı (artifact) olarak kaydeder. Ancak test sayınız arttıkça bu tekil iş (job) ciddi bir darboğaz oluşturacaktır.
Playwright Sharding Konfigürasyonu ve Matris Yapısı
Temel iş akışımızı oluşturduktan sonra, şimdi bu yapıyı paralel çalışacak şekilde optimize etme zamanı geldi. GitHub Actions, “Matrix Strategy” (matris stratejisi) adı verilen harika bir özellik sunar. Bu özellik sayesinde, tek bir iş tanımını farklı parametrelerle çoklu olarak klonlayabilir ve aynı anda çalıştırabilirsiniz. Playwright’ın sharding parametreleri ile GitHub Actions matris yapısını birleştirdiğimizde, tam otomatik bir paralel test canavarı elde ederiz.
Playwright test komutu çalıştırılırken iki kritik parametre kabul eder: --shard=x/y. Burada x mevcut parçanın indeksini, y ise toplam parça sayısını temsil eder. Örneğin, testleri 3 parçaya bölmek istiyorsak, çalıştıracağımız komutlar sırasıyla --shard=1/3, --shard=2/3 ve --shard=3/3 olacaktır. Bunu GitHub Actions üzerinde dinamik hale getirmek için matris yapısını şu şekilde kurgularız:
name: Playwright Sharded Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
playwright-tests:
timeout-minutes: 40
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
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 --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- name: Upload blob report to GitHub Actions Artifacts
if: always()
with:
name: all-blob-reports
path: blob-report/
retention-days: 1
Bu yeni konfigürasyonda neler değişti? İlk olarak, strategy.matrix bloğu altında shardIndex ve shardTotal değişkenlerini tanımladık. GitHub Actions, bu matris tanımını gördüğü anda arka planda 4 adet tamamen bağımsız sanal makine başlatır. Her bir makineye sırasıyla 1, 2, 3 ve 4 indeks değerlerini atar. İkinci önemli değişiklik ise test komutunun sonuna eklediğimiz dinamik parametredir. Son olarak, standart HTML raporu yerine “blob-report” çıktısı aldık. Çünkü her makine kendi parçasının sonucunu üretecektir ve bu parçalı raporları daha sonra birleştirmemiz gerekecektir.
Gerçek Zamanlı Vaka Analizi: E-Ticaret Platformunda Test Sürelerini %80 Azaltmak
Konuyu daha somut hale getirmek için Türkiye pazarında faaliyet gösteren hayali bir e-ticaret platformu olan “AlisverisSepeti” projesini ele alalım. Bu platformun QA (Quality Assurance – Kalite Güvence) ekibi, kullanıcıların sepet adımları, ödeme sistemleri, üyelik işlemleri ve ürün arama fonksiyonları için toplamda 480 adet karmaşık uçtan uca test senaryosu yazdı. Projede dil olarak TypeScript, test kütüphanesi olarak ise Playwright tercih edildi.
İlk başlarda tüm testler tek bir CI/CD hattında sıralı olarak çalıştırılıyordu. Ancak testlerin tamamlanması tam 55 dakika sürüyordu. Bu durum, yazılımcıların kodlarını canlıya (production) göndermeden önce saatlerce beklemesine yol açıyor ve şirketin çevikliğini ciddi şekilde baltalıyordu. Ekip, bu sorunu çözmek için Playwright Sharding mimarisine geçiş kararı aldı.
Yapılan analizler sonucunda test yükünün 8 farklı parçaya (shard) bölünmesine karar verildi. GitHub Actions matris yapısı 8 paralel iş çalıştıracak şekilde güncellendi. Sonuçlar gerçekten göz kamaştırıcıydı:
- Eski Test Süresi: 55 Dakika (Tekil makine)
- Yeni Test Süresi: 7.5 Dakika (8 Paralel Shard ile)
- Kazanılan Zaman Oranı: Yaklaşık %86 zaman tasarrufu
- Geliştirici Memnuniyeti: Kod dağıtım sıklığı günde 2’den 10’un üzerine çıktı.
Bu vaka analizi göstermektedir ki, doğru yapılandırılmış bir sharding stratejisi sadece teknik bir iyileştirme sunmakla kalmaz, aynı zamanda doğrudan iş çıktılarının hızlanmasına ve geliştirme ekiplerinin motivasyonunun artmasına katkı sağlar.
Test Raporlarını Birleştirme ve Yayınlama (Merge Reports)
Testlerimizi paralel olarak başarıyla koşturduk ve süreleri kısalttık. Ancak şu anda elimizde bir problem var: 4 veya 8 farklı makineden elde edilmiş, parça parça “blob” rapor dosyaları var. Yöneticilerimize veya ekibimize sunmak için bize tek bir derli toplu HTML raporu gerekiyor. Neyse ki Playwright, bu farklı parçalardan gelen raporları tek bir potada eritebilen merge-reports aracına sahiptir.
Bunun için GitHub Actions iş akışımıza ikinci bir iş (job) eklememiz gerekir. Bu iş, paralel çalışan tüm testlerin bitmesini bekleyecek, üretilen tüm blob raporlarını indirecek, bunları birleştirecek ve tek bir HTML raporu olarak yayınlayacaktır. İşte bu süreci otomatize eden tam iş akışı şeması:
jobs:
playwright-tests:
# (Yukarıda tanımladığımız sharding iş adımları buraya gelecek)
merge-reports:
if: always()
needs: [playwright-tests]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Download all blob reports
uses: actions/download-artifact@v4
with:
name: all-blob-reports
path: all-blob-reports
- name: Merge PDF/HTML Reports
run: npx playwright merge-reports --reporter html ./all-blob-reports
- name: Upload Final HTML Report
uses: actions/upload-artifact@v4
with:
name: html-report
path: playwright-report
retention-days: 14
Bu yapıda yer alan needs: [playwright-tests] ifadesi kritik bir öneme sahiptir. Bu ifade, rapor birleştirme adımının ancak ve ancak tüm paralel testler tamamlandıktan sonra çalışmaya başlayacağını garanti eder. actions/download-artifact adımı ise tüm farklı makinelerden toplanan blob raporlarını tek bir klasöre indirir. Ardından çalıştırılan npx playwright merge-reports komutu, sihirli bir şekilde tüm verileri birleştirerek bize tertemiz bir HTML raporu sunar.
CI/CD Süreçlerinde Karşılaşılan Sorunlar ve Çözüm Önerileri
Playwright ve GitHub Actions entegrasyonu harika çalışsa da, ölçek büyüdükçe bazı teknik zorluklarla karşılaşmanız olasıdır. Bu zorlukların üstesinden gelmek için uygulayabileceğiniz bazı pratik yöntemleri şu şekilde sıralayabiliriz:
- Kararsız Testler (Flaky Tests): Bazen testler yerel makinenizde sorunsuz çalışırken, CI/CD ortamında ağ gecikmeleri veya kaynak yetersizliği nedeniyle başarısız olabilir. Bu durumu engellemek için Playwright konfigürasyon dosyanızda (
playwright.config.ts) otomatik yeniden deneme (retry) mekanizmasını aktif hale getirin. Örneğin, CI ortamı içinretry: process.env.CI ? 2 : 0tanımı yapmak hayat kurtarır. - Önbellekleme (Caching) Kullanımı: Her test çalışmasında bağımlılıkların (node_modules) sıfırdan indirilmesi zaman kaybettirir. GitHub Actions’ın önbellekleme mekanizmasını kullanarak npm paketlerini önbelleğe alabilir ve kurulum adımlarını saniyelere indirebilirsiniz.
- Hassas Verilerin Güvenliği: Testleriniz gerçek veya test ortamı API’lerine bağlanırken kullanıcı adı, şifre veya API anahtarı gibi gizli bilgilere ihtiyaç duyabilir. Bu verileri asla kodunuzun içine düz metin olarak yazmayın. GitHub projenizin ayarlar kısmındaki “Secrets and Variables” bölümünü kullanarak bu verileri güvenli bir şekilde saklayın ve iş akışınızda
${{ secrets.API_KEY }}şeklinde çağırın.
Sıkça Sorulan Sorular (SSS)
Sharding kullanmak GitHub Actions maliyetlerimi artırır mı?
GitHub Actions, faturalandırmayı toplam kullanılan dakika bazında yapar. Örneğin, tek bir makinede 40 dakika süren bir testi, 4 makinede paralel olarak 10’ar dakika çalıştırmak teorik olarak aynı toplam dakikayı (4 x 10 = 40 dakika) harcar. Dolayısıyla faturalandırma üzerinde ciddi bir olumsuz etkisi olmaz, aksine geliştiricilerin bekleme süresini azalttığı için dolaylı yoldan verimliliği artırır.
Kaç adet shard kullanmam gerektiğine nasıl karar vermeliyim?
Bu durum projenizin büyüklüğüne ve test sayınıza bağlıdır. Genel bir kural olarak, toplam test süreniz 15 dakikayı aşıyorsa sharding düşünmeye başlamalısınız. İlk aşamada 2 veya 4 shard ile başlayıp, test süreleriniz tekrar uzamaya başladıkça bu sayıyı kademeli olarak artırabilirsiniz.
Paralel çalışan testler aynı veritabanını kullanırken çakışma yaşar mı?
Evet, bu en sık karşılaşılan mimari sorunlardan biridir. Eğer testleriniz veritabanında aynı verileri manipüle ediyorsa, paralel çalışırken birbirlerini bozabilirler. Bu sorunu aşmak için her testin kendi benzersiz test verisini (örneğin dinamik e-posta adresleri veya benzersiz ID’ler kullanarak) oluşturmasını sağlamalı veya her shard için izole test ortamları kullanmalısınız.
Playwright Sharding sadece TypeScript ile mi kullanılabilir?
Hayır, Playwright’ın sharding özelliği Python, Java ve .NET (C#) dillerini destekleyen diğer Playwright kütüphanelerinde de kullanılabilir. Ancak TypeScript ve JavaScript ekosistemi, sunduğu zengin araç desteği ve hızlı kurulum avantajları nedeniyle sektörde en çok tercih edilen seçenektir.
#GitHubActions #Playwright #TypeScript #ContinuousIntegration #SoftwareTesting