Playwright ile Kimlik Doğrulama Yönetimi

Otomasyon projelerinde (proje büyüklüğüne göre) binlerce test senaryosu yazarız.

Bu test senaryoların ilk yaptığı iş, genellikle sisteme giriş yapmaktır.

Sisteme giriş yapmak ve bu işlemi hemen hemen her test senaryosu için yapıyor olmak execution time’ı ciddi derecede artırır.

Execution time’ın artması, test otomasyon maliyetlerinin artması anlamına gelmektedir ve bu istemediğimiz bir şeydir.

Hayali bir proje düşünelim. Bu projede tüm test suitini çalıştırdığımızda, sisteme giriş yapmak için ne kadar zaman harcıyoruz birlikte kabaca hesaplayalım:

  • Login işlemi gerektiren toplam test adedi: 500

  • Ortalama login olma süresi: 10 saniye

  • 500 senaryo için, login olmakla geçirdiğimiz dakika: 500 × 10 / 60 = 83,3 dakika

Hesap ortada, orta ölçekli bile denilemeyecek hayali projemizde sisteme giriş yapmak için 83,3 dakika harcıyoruz.

Pekala! Eminim senin de aklına gelmiştir: “Sisteme bir kere giriş yapsak, ardından oturumu kayıt etsek, giriş yapmayı gerektiren diğer senaryolar ilgili oturuma ait bilgileri kullansa“ Bu durumda giriş yapmakla geçirdiğimiz 5.000 saniye, 10 saniyeye düşmüş olmaz mı? Bu 5.000 / 10 = 500 katlık performans iyileştirmesi anlamına geliyor 😁

Hadi Kolları Sıvayalım

İşe sıfırdan bir proje oluşturmakla başlayalım. Projeyi oluşturmak için bu linki ziyaret edebilirsin. PC’de Node.js yüklü olduğundan emin olman gerekmekte.

İlk olarak “login once“ isminde bir test senaryosu oluşturuyorum. Bu test senaryosu, sisteme giriş yaptığım adımları içeriyor. Siz bu metodu, giriş yapmak istediğiniz web sitesine göre düzenleyebilirsiniz.

Not: Sisteme login olduktan sonra oturum bilgilerinin oluşabilmesi için mutlaka doğrulama vb. işlem yapmak (bir miktar zaman geçirmek) gerekiyor. Bu tür kontrolleri yapmadan direkt dosyaya yazmaya çalıştığınızda oturum bilgileri oluşmamış olabiliyor ve gerekli bilgiler dosyaya yazılamıyor.

// setup.ts

import { test as setup, expect } from '@playwright/test';

// kaydedilen kimlik doğrulama bilgileri, standartUser.json dosyasına yazılacak
const authFile = './pwAuth/.auth/standartUser.json';

setup('login once', async ({ page }) => {

    // Login olmak istediğin siteye ait implementasyonları burada uygula.
    await page.goto('http:tiklagelsin.com/account/sign-in');
    await page.locator("//*[@name='username']").fill('your_user_name');
    await page.locator("//*[@name='password']").fill('your_password');
    await page.getByTestId('submitBtn').click();
    // oturum ve çerezlerin oluşması için sayfanın yüklendiğinden emin olmalısın.
    // sayfanın yüklendiğinden emin olmanın yolu assertion'dan geçiyor.
    await expect(page.locator('text=burada_sadece_login_durumda_gorebildiğin_text_gelecek')).toBeVisible();

    //Harika! Login olduk, artık oturum bilgilerini dosyaya yazalım.
    await page.context().storageState({ path: authFile });
});

Sisteme giriş yapıp, oturum bilgilerini kayıt eden metodu yazdığımıza göre, geriye ilgili metodun tüm testlerden önce bir kere çalıştırılması kalıyor. Bunun için bir setup projesi oluşturup, asıl projeme bağımlılık olarak ekliyorum. Ek olarak, asıl projem (testlerin koştuğu proje, chromium) olan storageState yoluna, kimlik doğrulama yaparken kayıt ettiğimiz dosyanın yolunu yazmamız gerekiyor.

playwright.config.ts dosyası içinde projects kısmı böyle görünüyor olmalı:

 //playwright.config.ts
  projects: [
    {
      name: 'setup',
      testMatch: 'setup.ts'
    },
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        storageState: './pwAuth/.auth/standartUser.json'
      },
      dependencies: ['setup']
    },
  ]

Son Birkaç Ayar

  • login testini yazdık

  • setup projesi oluşturduk

  • setup projesini, asıl projeye bağımlılık olarak ekledik

Playwright extension’a tıklayıp, projects bölümünde setup ve chromium projelerinin seçili olduğundan emin olalım.

Son olarak, testlerimi login olduğumu düşünerek yazmaya devam ediyorum. Artık herhangi bir testi çalıştırdığınızda:

  • İlk olarak setup projesi çalışacak (fail verirse, geriye kalan testler ignore edilir)

  • Setup projesi çalıştıktan sonra kimlik bilgilerim kayıt edilmiş olacak.

  • Akabinde asıl projem olan chromium çalışmaya başlayacak. storageState kısmında belirttiğimiz dosyadan kimlik bilgilerini okuyacak. Bu sayede tekrar login olmaya gerek duymadan testlerimizi çalıştırabileceğiz.

// example.spec.ts

test('continue as if you are logged in', async ({ page }) => {
    // şu an login olmuş durumdasın.
    // login adımından sonra yaptığın işlemlere devam edebilirsin.
});

Testleri Çalıştırabiliriz

Terminal ekranına gidip npx playwright test yazarak testlerimizi çalıştıralım. Her şey yolunda gittiyse aşağıdaki şekilde bir sonuç görmeniz gerekmekte:

Kontrollerimi yaptığımda, session dosyası oluşmuş, test senaryom bu dosyayı okuyup teste devam edebilmiş. 🎉🎉

Performans Etkileri Üzerine Genel Bakış

Kendi projemde testleri:

  • Login statüsünü kullananlar

  • Her seferinde login işlemi yapan senaryolar olmak üzere ikiye ayırdım

Sonrasında performans ölçümü için ilgili testleri paralel ve seri(single thread) olarak çalıştırdım ve toplam süreleri kayıt ettim. Sonuçlar tablodaki gibi:

Login (dakika)Non-login(dakika)
1. çalıştırma (12 test, 3 paralel)1,41,5
2. çalıştırma (12 test, 3 paralel)1,51,4
3. çalıştırma (12 test, 3 paralel)1,91,7
4. çalıştırma (12 test, 3 paralel)1,71,7
5. çalıştırma (12 test, 3 paralel)21,5
Login (dakika)Non-login(dakika)
1. çalıştırma (5 test, seri)11,2
2. çalıştırma (5 test, seri)1,11,2
3. çalıştırma (5 test, seri)1,11,1
4. çalıştırma (5 test, seri)1,11,1
5. çalıştırma (5 test, seri)1,11,2

Sonuç

Bir kere login olup, session’ı testlerimiz arasında paylaşabildik. Yukarıdaki tabloları incelediyseniz oturum paylaşım geliştirmesinin zaman kazanımı konusunda herhangi bir getirisi olmadığını fark etmişsinizdir.

Belki sonuçlar sizin sistemlerinizde farklılık gösterebilir, bunları test etmeden bilemeyiz. Belki de olaya sadece zaman kazanımı açısından değil farklı bir perspektiften bakmak gerekir, mesela: login olma kodunun tekrarlanmaması gibi.

Bir sonraki yazıda görüşmek dileğiyle 👋👋