Türkçe
  • test
  • uçtan uca test
  • entegrasyon testi
  • geliştirici
  • verimlilik
  • jest
  • puppeteer

jest-puppeteer ile uçtan uca testler yazma konusunda hızlı bir rehber

Bu makale, jest-puppeteer ile verimli uçtan uca testler yazma konusunda hızlı bir rehber sunarak kurulum sürecine, yaygın olarak kullanılan API'lere ve basit bir yapılacaklar uygulaması örneği üzerinden pratik test senaryolarına vurgu yapıyor.

Yijun
Yijun
Developer

Logto'nun kalitesini sağlama ve sürekli iyileştirme taahhüdümüzün bir parçası olarak, uçtan uca otomatik testler için jest-puppeteer kullanıyoruz. Bu, Logto'nun geliştirme sürecini aksama olmadan hızlı bir şekilde yinelememizi sağlar.

Bu makalede, basit bir yapılacaklar uygulaması örneği kullanarak verimli jest-puppeteer test betikleri yazma konusundaki deneyimlerimizi paylaşacağız. Amacımız, kendi projeleriniz için jest-puppeteer test kodu yazmaya hızlı bir şekilde başlamanıza yardımcı olmaktır.

jest-puppeteer ile uçtan uca testlere giriş

Uçtan uca testler, uygulamanızın kullanıcı perspektifinden doğru çalıştığını doğrulamanın bir yoludur. Bunu başarmak için iki temel aracı kullanırız: Jest ve Puppeteer.

Jest, testler ve çıkarımları yazmak için kullanıcı dostu bir API sunan popüler bir JavaScript test çerçevesidir. Birim ve entegrasyon testleri için geniş çapta kullanılır.

Puppeteer, Chrome ekibi tarafından geliştirilen ve başsız Chrome veya Chromium tarayıcıları kontrol etmek için yüksek düzeyde bir API sağlayan bir Node.js kütüphanesidir. Bu, uçtan uca testlerde tarayıcı etkileşimlerini otomatikleştirmek için ideal bir seçim yapar.

jest-puppeteer, Puppeteer ile uçtan uca testleri etkinleştiren bir Jest ön ayarıdır. Yeni tarayıcı örneklerini başlatmak ve web sayfalarıyla etkileşim kurmak için basit bir API sunar.

Artık temel araçları anladığınıza göre, test ortamınızı kurmaya başlayalım.

Test ortamınızı kurma

jest-puppeteer ile uçtan uca testler için test ortamınızı kurmak, üç ana adımdan oluşan basit bir işlemdir:

  1. Bağımlılıkları yükleyin

Projenizde (veya yeni bir proje oluşturun) terminali açın ve şu komutu çalıştırın:

Ardından node_modules/puppeteer dizinine gidin ve Puppeteer için gerekli olan Chromium'u yükleyin:

  1. Jest'i yapılandırın

Sonrasında, Jest'i Puppeteer ile sorunsuz çalışacak şekilde yapılandırmanız gerekir.

Projenizin kök dizininde bir jest yapılandırma dosyası (ör. jest.config.js) oluşturun veya zaten varsa, bu dosyada jest-puppeteer'i bir ön ayar olarak belirtin:

Bu dosyada diğer Jest ayarlarını gerektiği şekilde özelleştirebilirsiniz. Jest yapılandırmalarını özelleştirme hakkında daha fazla bilgi için Jest yapılandırma dökümanına başvurabilirsiniz.

  1. Testlerinizi yazın

Projenizde test dosyaları oluşturun, genellikle .test.js uzantısıyla adlandırılır. Jest bu test dosyalarını otomatik olarak bulacak ve çalıştıracaktır.

İşte Jest dökümanından bir örnek:

Ardından testi çalıştırmak için şu komutu çalıştırın:

Bu üç adımı uygulayarak jest-puppeteer kullanarak uçtan uca testler yürütmek için iyi yapılandırılmış bir test ortamına sahip olacaksınız.

Ancak, bunun sadece basit bir örnek olduğunu unutmayın. Ortam yapılandırması hakkında daha ayrıntılı bilgi için ilgili dökümantasyona başvurabilirsiniz:

Yaygın olarak kullanılan API'ler

Gelecek adımlarda, testlerimizde Jest, Puppeteer ve jest-puppeteer tarafından sağlanan API'lere güveneceğiz.

Jest, testleri düzenlemek ve beklenen sonuçları doğrulamak için öncelikle API'ler sunar. Belirli ayrıntıları dökümanlarda keşfedebilirsiniz.

Puppeteer'in API'leri tarayıcılarla etkileşim kurmak için tasarlanmıştır ve testler için destekleri daha az doğrudan olabilir. Sağladıkları işlevleri anlamak için Puppeteer dökümantasyonuna başvurabilirsiniz. Sonraki test örneklerimizde bazı yaygın kullanım durumlarını ele alacağız.

Puppeteer'in API'leri başlangıçta test yazmak için tasarlanmadığından, onları kullanarak test yazmak zorlayıcı olabilir. Puppeteer testlerinin yazım sürecini kolaylaştırmak için jest-puppeteer, expect-puppeteer adlı yerleşik bir kütüphane içerir. Bu kütüphane, kısa ve kullanıcı dostu bir dizi API sunar. Kütüphane hakkında daha fazla bilgi dökümantasyonunda bulunabilir ve aşağıdaki örneklerde bazı faydalı özellikler tanıtılmaktadır:

Sonraki örneklerde, bu kütüphaneler tarafından sağlanan API'leri test senaryolarımızı tamamlamak için birleştireceğiz.

Şimdi basit yapılacaklar uygulaması ile test kodu yazmayı öğrenmeye başlayalım.

Basit yapılacaklar uygulaması

Varsayalım ki http://localhost:3000 üzerinde çalışan basit bir yapılacaklar uygulamamız var, bu uygulamanın temel HTML kodu şu şekildedir:

Uçtan uca testler yaparken aşağıdaki senaryoları kapsamalıyız:

  1. Uygulamanın URL'sini açtığımızda, uygulama ve verileri doğru şekilde yüklenmelidir.
  2. Öğenin kontrol et düğmesi tıklanabilir olmalıdır.
  3. Öğe notlarına tıklanarak dış bir bağlantının yeni bir sekmede açılması gerekir.
  4. Formdan bir öğe eklenebilir.

Daha sonra, bu senaryoları doğrulamak için test kodu yazacağız.

Uygulamanın ve verilerin yüklendiğini varsayın

Uygulamanın yüklendiğini başarıyla kabul etmemiz için şu koşulların yerine getirilmesi gerekir:

  1. URL'ye eriştikten sonra sayfada "app" ID'sine sahip bir eleman bulunmalıdır.
  2. Uygulama içindeki veri doğru şekilde görüntülenmelidir.

Bu yüzden aşağıdaki test kodunu yazdık:

Kodda:

  • page.goto, "http://localhost:3000" yazmaya eşdeğerdir, bu da herhangi bir URL'ye gitmenizi sağlar.
  • page.waitForSelector, belirli bir CSS seçicisinin belirli bir öğeyle eşleşmesini beklemek için kullanılır ve varsayılan bekleme süresi 30 saniyedir.
  • expect(page).toMatchElement expect-puppeteer kütüphanesinden gelir ve page.waitForSelector ile benzerdir, ancak aynı zamanda bir öğe içindeki metni de eşleştirmeyi destekler. Ayrıca, toMatchElement için varsayılan zaman aşımı yalnızca 500ms'dir.

İlk bakışta mükemmel görünüyor olabilir, ancak bu testi çalıştırırken ve bir CI ortamına dağıtırken, birden fazla yürütmeden sonra zaman zaman başarısız olur. Hata mesajı şu şekildedir:

Başarısızlık bilgisine ve bu testin çoğu zaman geçtiği gerçeğine dayanarak, uygulamanın başlatılmasından sonraki ilk 500ms içinde istenen verilerin her zaman dönmediğini çıkarabiliriz. Bu nedenle, verilerin yüklenmesini beklemek ve ardından doğrulama yapmak istiyoruz.

Genellikle, bunu başarmanın iki yaygın yaklaşımı vardır:

  1. Doğrulama bekleme süresini artırın

Hata mesajından, toMatchElement için varsayılan bekleme süresinin 500ms olarak ayarlandığını görebiliriz. Bu süreyi şu şekilde fonksiyona timeout seçeneğini ekleyerek artırabiliriz:

Bu yaklaşım, başarısız testlerin meydana gelmesini biraz azaltabilir, ancak sorunu tamamen çözmez çünkü verilerin ne kadar sürede alınması gerektiğini kesin olarak bilemeyiz.

Bu nedenle, yalnızca belirli bir bekleme süresinden emin olduğumuz durumlarda, bu yaklaşımı, örneğin "bir öğenin üzerine 2 saniyeden fazla süreyle gelindikten sonra bir ipucunun (tooltip) belirlenmesi” gibi senaryolarda kullanırız.

  1. Bir doğrulama yapmadan önce ağ isteğinin tamamlanmasını bekleyin

Bu doğru yaklaşımdır. Verinin ne kadar süreceğini bilmesek de, ağ isteğinin bitmesini beklemek her zaman güvenli bir seçimdir. Bu noktada, ağ isteklerinin tamamlanmasını beklemek için page.waitForNavigation({ waitUntil: 'networkidle0' }) kullanabiliriz:

Bu şekilde, uygulama ve yüklü verileri doğrulamak için bir doğrulama yapmadan önce ağ isteklerinin sona erdiğinden emin olabiliriz. Bu, testin sürekli olarak doğru sonuçlar vermesini sağlar.

Belirli bir düğmeye tıklamayı bekleyin

Sonraki adımda, bir öğe içindeki kontrol et düğmesine tıklama işlevselliğini test ediyoruz.

Örnek uygulamada, tüm öğelerin aynı yapıya sahip olduğunu fark ettik. Kontrol et düğmeleri, li[class$=item] > button CSS seçicisini kullanarak tıklanabilir ve düğme metni her zaman "Kontrol Et"tir. Bu nedenle hangi öğeye tıklanacağını doğrudan belirtmemiz mümkün değildir. Bu yüzden yeni bir çözüm bulmalıyız.

"Logto başlarken dökümanını oku" öğesinin kontrol et düğmesine tıklamak istediğimizi varsayalım. Bunu iki adıma ayırabiliriz:

  1. İlk olarak, belirtilen öğeye bir referans alın.
  2. Ardından, o öğe içindeki kontrol et düğmesine tıklayın.

Kodda gösterildiği gibi, itemName "Logto başlarken dökümanını oku" olarak ayarlanmış öğeyi eşleştirmek için toMatchElement fonksiyonunu kullanıyoruz. Ardından readDocItem referansını kullanarak altında bulunan "Kontrol Et" metin içerikli düğmeye tıklıyoruz.

Önemli bir nokta, readDocItem referansını alırken kullanılan CSS seçicinin li[class$=item]:has(div[class$=itemName]) olduğudur. Bu seçici öğenin kök li elemanını eşleştirir, çünkü sonrasında li etiketinin altında bulunan düğmeye tıklamayı amaçlıyoruz.

expect(readDocItem).toClick kullanımı toMatchElemente benzer. Örnek kodda, düğmenin 'Kontrol Et' metin içeriğini daha fazla eşleştirmek için { text: 'Kontrol Et' } geçiriyoruz. Ancak düğmenin metin içeriğini eşleştirip eşleştirmemek ihtiyaçlarınıza bağlıdır.

Dış bir bağlantının yeni bir sekmede açıldığını varsayın

Sıradaki adımda, bir öğe notları içinde bulunan bağlantıya tıklanarak dış bir bağlantının yeni bir sekmede açılıp açılmadığını test etmek istiyoruz.

Örnek uygulamada, "Logto başlarken dökümanını oku" öğesi, notlar içinde Logto dökümanına dış bir bağlantıya sahiptir. İşte test kodumuz:

Kodda, toClick kullanarak itemNotes içindeki bağlantıya tıklıyoruz.

Sonrasında, browser.waitForTarget kullanarak "https://docs.logto.io/docs/tutorials/get-started" URL'sine sahip yeni bir sekme yakalarız.

Sekme elde edildikten sonra, Logto döküman sayfasının bir örneğini almak için target.page() kullanıyoruz ve sayfanın yüklendiğinden emin oluruz.

Ayrıca, testimizi tamamladıktan sonra yeni açılan sayfayı kapatmayı unutmayın.

Formdan bir öğe oluşturulacağını varsayın

Şimdi, bir öğe ekleme işlevini test etmek istiyoruz.

Formdaki öğe adını ve öğe notlarını doldurmamız, "Ekle" düğmesine tıklamamız ve eklediğimiz içeriğin listede görünüp görünmediğini kontrol etmemiz gerekiyor:

Form içeriklerini doldurmak için expect(page).toFill(inputSelector, content) fonksiyonunu kullandığımızı fark edeceksiniz. Bu fonksiyon, girdideki tüm içeriği content ile değiştirecektir.

Eğer var olan içeriği değiştirmeden sadece bazı karakterler eklemek istiyorsanız, page.type(selector, content) kullanarak girdiye eklemek istediğiniz içeriği doğrudan ekleyebilirsiniz.

Ancak, formumuzda doldurulacak birçok alan varsa, toFill fonksiyonunu birden fazla kez çağırmak pek de uygun değildir. Bu durumda içerikleri tek bir çağrıda doldurmak için aşağıdaki yaklaşımı kullanabiliriz:

Sağlanan nesne anahtarı, input elemanının name niteliğidir.

Özet

jest-puppeteer kullanarak uçtan uca testler yaparken yaygın test gereksinimlerine yönelik basit bir örnek ve buna uygun kod yazma tekniklerini ele aldık. Umarız jest-puppeteer test kodu yazmanın temellerini hızlı bir şekilde kavramanıza yardımcı olabilir.