Cypress ile Test Otomasyon Stratejileri

Halil İbrahim Ayhan
Sahibinden Technology
6 min readJul 26, 2023

İlk yazımda Cypress’in ne olduğunu, nasıl çalıştığını, avantaj ve dezavantajlarını, bunların yanı sıra Cypress kullanan şirketleri, kullanım istatistiklerini ve Cypress ile test yazarken kullanabileceğiniz kodlara örnekler vermiştim.

Şimdi Cypress’in biraz daha derinlerine inmek istiyorum. Cypress’in temel özellikleri, dom manipülasyonları, döngü kullanarak birden fazla data üzerinden test yapmayı, hata senaryolarını, beğendiğim bazı kütüphaneleri ve bunlar hakkında bazı bilgileri anlatacağım sizlere.

Cypress’in Temel Özellikleri; Form Gönderme ve Komut Setleri

describe('Kayıt Formu', function() {
it('Yeni Kullanıcı Kaydı', function() {
// Formun bulunduğu sayfayı ziyaret edin
cy.visit('http://localhost:3000/kayit')

// İsim alanını doldurun
cy.get('input[name="adSoyad"]')
.type('Ali Veli')
.should('have.value', 'Ali Veli')

// Email alanını doldurun
cy.get('input[name="email"]')
.type('aliveli@gmail.com')
.should('have.value', 'aliveli@gmail.com')

// Şifre alanını doldurun
cy.get('input[name="sifre"]')
.type('123abc')
.should('have.value', '123abc')

// Şifre onay alanını doldurun
cy.get('input[name="sifre_tekrari"]')
.type('123abc')
.should('have.value', '123abc')

// Kayıt Ol düğmesine tıklayın
cy.get('form').submit()

// Kayıt işleminin başarılı olduğunu doğrulayın
cy.url().should('include', '/kayit/basarili')

cy.get('.success-message')
.should('contain', 'Kaydınız Başarılı. Sayın Veli, Hoşgeldiniz!')

// Veritabanında yeni kullanıcının oluşup oluşmadığını kontrol edin.
// Bu örnek, bir API endpoint'i kullanıyor; sizin durumunuza göre değişiklik gösterebilir.
cy.request('GET', 'http://localhost:3000/api/users?email=aliveli@gmail.com')
.its('body')
.should('contain', { email: 'aliveli@gmail.com' })
})
})

Cypress ile DOM Manipülasyonu

Cypress çok yetenekli bir otomasyon aracı olduğu için Document Object Model dediğimiz DOM üzerinde de işlem yapabiliyor. Peki DOM manipülasyonu nedir ? DOM Manipülasyonu sayfanıza element ekleyip çıkarmak text değerini değiştirmek, combobox’tan veya bir radio button ‘dan değer seçme işlemlerine örnektir.

Şunu da belirtmeliyim ki Cypress’in Document Object Model üzerindeki manipülasyonu test etmek veya değerleri doğrulama amaçlarıyla sınırlıdır. Bir uygulamada fonksiyonu veya belirli bir işlevi değiştirmek için tasarlanmamıştır.

Örneğin yukarıda örnek verdiğim Kayıt Formunda olduğu gibi Cypress ile formdaki alanları doldurmak ve Kayıt Ol düğmesine tıklamak için DOM üzerinde manipülasyon yaparız, ancak bu manipülasyon uygulamamızın herhangi bir işlevini değiştirmiyor. Son kullanıcının gerçekleştireceği bir eylemi simüle etmemize yarıyor.

Cypress ile Otomatik Bekleme

Cypress’in otomatik bekleme (automatic waiting) özelliği; testlerinizin hızlı ve güvenilir bir şekilde çalışmasını sağlar. Testiniz çalışırken cypress otomatik olarak bekler ve testinizle ilgili koşulların yerine getirilmesini sağlar. Bu sayede testinizi belirli bir süre bekletip zaman kaybetmenizin önüne geçer. Dinamik olarak koşulunuzu kontrol eder ve koşul gerçekleştiği anda beklemeyi durdurup sonraki adıma geçer.

Elementin Görünürlüğünü Bekleme
Cypress elementinizin DOM üzerinde olmasını otomatik olarak bekleyebilir. Bazen elementler sayfa açılır açılmaz görünür olmayabilir. Bu özellik sayesinde belirli bir süre boyunca sayfanızı kontrol eder.

cy.get('#elementId'{ timeout: 10000 }) // #10 saniye boyunca elementId id'sine sahip bir elementin var olmasını bekler

Elementin Belirttiğiniz Bir Durumda Olmasını Bekleme
Cypress spesifik bir elementin görünür olmasını, aktif veya pasif olmasını otomatik olarak bekleyebilir.

cy.get('submitButton').should('be.visible') // submitButton class isimli elementin görünür olmasını bekler
cy.get('email').should('be.enabled') // email isimli input alanının etkin olmasını bekler

Dikkat ettiyseniz hemen üstteki örnekte belirli bir timeout değeri girmedim. Cypress eğer siz bir değer girmezseniz default olarak 4 saniye bekleme işlemi yapar. (Timeout değerini milisaniye tipinde girmeniz gerekiyor.)

Cypress ile Birden Fazla Veriyi Kullanarak Test Yapma

Cypress for,foreach gibi döngü yapılarını kullanarak, birden fazla veriyi “aynı test üzerinde” kontrol etmeniz gereken durumlarda kod tekrarının önüne geçerek testlerinizi çalıştırabilmenize olanak sağlar.

describe('Birden fazla veriyi Döngü yapılarını kullanarak Test Etme', () => {
const providerContentInfo = [
{category: 'Otomobil', group: 'Alım Öncesi'},
{category: 'Kamyon', group: 'Alım Sonrası'}
]

providerContentInfo.forEach(provider=> {
var category = provider.category;
var group = provider.group;
it(`Yeni İçerik Oluşturma -> ${category} - ${group}`, () => {
cy.visit('https://loremipsum.com/form') // Form sayfasını açar
cy.get('input[name="category"]').type(category) // Kategori alanını doldurur
cy.get('input[name="group"]').type(group) // Grup alanını doldurur
cy.get('form').submit() // Formu gönderir

})
})
})

Hata Durumlarına Yönelik Senaryolar Hazırlama

Cypress kullanarak uygulamanızdaki hata durumlarını test edebilirsiniz. Kullanıcıların bir form üzerinde boş form gönderme durumu, geçersiz e-posta adresi girmesi gibi durumları kontrol edebilirsiniz.

describe('Form Hata Yönetimi Testleri', () => {
it('Geçersiz e-posta adresi girildiğinde hata mesajı görüntülenmelidir', () => {
cy.visit('https://loremipsum.com/form') // Form sayfasını açar
cy.get('input[name="email"]').type('geçersiz e-mail adresi') // Geçersiz bir e-posta adresi girer
cy.get('form').submit() // Formu gönderir

// Hata mesajının göründüğünü kontrol eder
cy.get('.error-message').should('be.visible')
cy.get('.error-message').should('contain', 'Lütfen geçerli bir e-posta adresi girin.')
})

it('Boş form gönderildiğinde hata mesajı görüntülenmelidir', () => {
cy.visit('https://loremipsum.com/form') // Form sayfasını açar
cy.get('form').submit() // Formu boş olarak gönderir

// Hata mesajının göründüğünü kontrol eder
cy.get('.error-message').should('be.visible')
cy.get('.error-message').should('contain', 'Bu alanın doldurulması zorunludur.')
})
})

Cypress ile Test Datalarının Yönetimi

Testleriniz sırasında kullanmanız gereken sabit değerler için Cypress’te fixture’lar kullanılır. Fixture dosyaları ‘cypress/fixtures’ klasöründe yer alır ve json,txt,csv gibi birden fazla dosya türünü destekler.

Fixture için bir örnek yapalım;
Öncelikle ‘cypress/fixtures’ klasöründe “kullanicilar.json” isimli bir dosya oluşturalım ve içerisine aşağıdaki değerleri yazalım.

{
"id": 1,
"kullaniciAdi": "Ali Veli",
"email": "aliveli@gmail.com"
}

Bu oluşturduğumuz veriyi testimizde kullanalım:

describe('Fixture Kullanımı', function() {
it('Fixture dosyasından veri oku', function() {
cy.fixture('kullanicilar.json').then((user) => {
cy.visit('http://loremipsum.com')
cy.get('input[name="kullaniciAdi"]').type(user.kullaniciAdi)
cy.get('input[name="email"]').type(user.email)
})
})
})

Örneğimizde ‘kullanicilar.json’ dosyasını ‘cy.fixture’ fonksiyonu ile yükleyip dönen objeyi formumuza girdik. Cypress ile geliştirdiğiniz testlerinizde statik verileriniz varsa veya hassas veriler içeren datalarınızı testlerde direkt olarak kullanmak istemiyorsanız fixture kullanmanızı öneririm.

Cypress ile Testlerinizin Parallel Çalışması

Projenizde çok fazla sayıda testiniz varsa, testlerinizin tek bir makinede seri olarak tamamlanması uzun sürebilir. Cypress birçok sanal makine üzerinde testlerinizin paralel olarak çalışmasına olanak sağlar. CI-CD süreçlerinizde Continuous integration adımında daha hızlı sonuç almanıza yardımcı olur.

from https://docs.cypress.io/guides/guides/parallelization

Cypress’in kendi blog’unda yazdığı benim de kullanırken tecrübe edindiğim bir husus var. Testlerinizi ne kadar çok fazla dosyada bulundurursanız performansı o kadar iyi oluyor. Örneğin 1 adet spec dosyasına 5 adet test yazacağınıza, 5 testi 2 veya 3'lü grup haline getirip 1'den fazla spec dosyasına bu testleri yazmanız çok daha iyi sonuçlar almanızı sağlar. Cypress Balans stratejisinde yukarıdaki resimden de göreceğiniz üzere CI Machine #1 adlı makinede admin.spec.js isimli testimiz bittiği anda henüz başlamamış olan search.spec.js isimli test dosyamızı #1 numaralı makinede koşacak şekilde ayarlıyor.

Cypress Dashboard üzerinden de testlerinizin paralel olarak daha hızlı koşması ile ilgili Cypress’in önerilerini takip edebilirsiniz. Yukarıdaki örnekte 10 makine ile koştuğumuz testler 11 dakika civarı sürmüş. Cypress ise bize 19 makine ile yaklaşık %37 zaman tasarrufu sağlayabileceğimizi belirtmiş.

Testlerinizi Paralel olarak çalıştırmak için aşağıdaki satırı package.json dosyanıza yazmanız gerekiyor.

cypress run --record --key YOUR_RECORD_KEY --parallel

Cypress’te Kullanabileceğiniz Kullanışlı Kütüphaneler

İlk yazımda da yazdığım gibi cypress çok geniş bir community desteğine sahip, ve kendi ekipleri de sürekli yeni versiyonlar çıkararak ürünlerini güncel tutmayı başarıyorlar.

Cypress ile testlerinizi yazarken kullanabileceğiniz bazı kütüphanelerden bahsetmek istiyorum;

cypress-visual-regression: Bu eklentiyi kullanarak projenizde görsel regresyon testlerini gerçekleştirebilirsiniz. Uygulamanızın farklı çözünürlük ve tarayıcılarda nasıl göründüğünü test edebilirsiniz.
(https://github.com/cypress-visual-regression/cypress-visual-regression)

/// <reference types="cypress" />
describe(`Describe: Google Visual Regression Tests`, () =>
{
it('Google logo görsel kontrolü', ()=>
{
cy.visit("https://www.google.com")

cy.get(".lnXdpd").compareSnapshot('googleImage',0.15)
})
})

cypress-iframe: Cypress iframe’lere doğrudan erişim desteği sunmuyor. Testlerinizi koşarken sayfa içerisindeki iframe elementlerine de erişmek isterseniz bu eklenti ile doğrudan erişebilirsiniz.
(https://www.npmjs.com/package/cypress-iframe)

cypress-multi-reporters: Birden fazla test sonucunu json,xml,html gibi dilediğiniz formatta rapor sunabilirsiniz.(https://github.com/you54f/cypress-multi-reporters)

Cypress’te kullanabileceğiniz diğer kütüphaneler için https://docs.cypress.io/plugins adresini ziyaret edebilirsiniz.

Cypress Community Desteği

Cypress ile ilgili cypress teknik ekibinden bilgi alabileceğiniz gibi, Stack OverFlow, GitHub gibi bilgi paylaşım platformlarına da bakabilirsiniz.

Açık kaynak kodlu bir proje olması sebebiyle özellikle GitHub üzerinde kullanıcılar yaşadıkları olumsuz deneyimleri, hataları veya özel isteklerini bildiriyorlar. Cypress ekibi de çok hızlı bir şekilde bu istekleri cevaplıyor.

Stack Overflow üzerinden de cypress tag’i altında birçok soru ve cevap bulabilirsiniz.

Cypress’in birde Kendi Discord kanalı bulunuyor. Cypress’in discord kanalına https://discord.com/invite/cypress linki üzerinden ulaşabilirsiniz.

Vakit ayırıp yazımı okuduğunuz için teşekkür ederim. Herhangi bir sorunuz varsa yorum olarak yazabilirsiniz, daha fazlası için beni takip edebilirsiniz. :)

--

--