Takip et

Cypress E2E Testine Neden İhtiyacımız Var ve Temelleri Nelerdir?

Uçtan Uca Testlerde Cypress: Uzmanlaşmanız Gereken Teknik Konular

Cypress ile uçtan uca testlerinizi etkin bir şekilde otomatikleştirmek ister misiniz? Temel prensiplerden ileri düzeye, Cypress’te master etmeniz gereken kilit teknik konuları keşfedin. Bu makale, sizi gerçek dünya senaryolarıyla donatarak test otomasyonu yolculuğunuzda bir adım öne taşıyacak. Modern web uygulamalarının karmaşıklığı düşünüldüğünde, sağlam bir test stratejisi geliştirmek artık bir lüks değil, bir zorunluluktur.

Modern web uygulamaları, tek sayfa uygulamaları (SPA) ve karmaşık etkileşimlerle doludur. Bu durum, geleneksel manuel test yöntemlerini yetersiz ve zaman alıcı hale getirir. İşte tam da bu noktada uçtan uca (E2E) test otomasyonu devreye girer. Peki, neden özellikle Cypress’i tercih etmeliyiz? Cypress, diğer test araçlarının aksine, doğrudan tarayıcı içinde çalışır ve bu sayede uygulamanızla tıpkı bir kullanıcı gibi etkileşim kurar. Bu, asenkron işlemlerin, DOM manipülasyonlarının ve tarayıcı olaylarının çok daha doğru ve güvenilir bir şekilde test edilmesini sağlar. Geleneksel WebDriver tabanlı araçlar, tarayıcı dışından iletişim kurarken, Cypress, test kodunuzu uygulamanızla aynı çalışma zamanında çalıştırarak bu gecikmeyi ve karmaşıklığı ortadan kaldırır. Böylece, geliştirme döngüsünü hızlandıran ve hata ayıklamayı basitleştiren eşsiz bir test deneyimi sunar.

Cypress’in en çekici özelliklerinden biri, kurulumunun son derece kolay olmasıdır. npm veya yarn kullanarak birkaç basit adımla projenize entegre edebilirsiniz. Kurulumun ardından, ilk testinizi yazmak oldukça sezgiseldir. Aşağıdaki örnek, temel bir sayfa ziyaretini ve bir elementin varlığını doğrulayan basit bir Cypress testi göstermektedir. Bu test, Cypress’in ne kadar okunabilir ve anlaşılır bir sözdizimi sunduğunu net bir şekilde ortaya koymaktadır. Testleriniz, tarayıcıda eş zamanlı olarak çalıştırılabilir ve komutlar arasındaki tüm adımları görsel olarak takip edebilirsiniz, bu da hata ayıklama sürecini inanılmaz derecede kolaylaştırır. Bir testin nasıl başarısız olduğunu ve hangi aşamada sorun yaşandığını anında görebilirsiniz. Bu yetenek, özellikle karmaşık kullanıcı akışlarını test ederken kritik öneme sahiptir.

Uzman İpucu: Cypress’in tarayıcı içi çalışma mimarisi, testlerinizin uygulamanıza daha yakın olmasını sağlar. Bu sayede, kullanıcının gerçek deneyimini en iyi şekilde simüle edebilir ve entegrasyon sorunlarını erken aşamada tespit edebilirsiniz.

Cypress Kurulumu ve İlk Test Adımları Nasıl Olmalıdır?

Cypress’i projenize dahil etmek oldukça basittir. İlk adım olarak, projenizin kök dizininde aşağıdaki komutu çalıştırarak Cypress’i bağımlılık olarak ekleyebilirsiniz:


npm install cypress --save-dev
# veya
yarn add cypress --dev

Kurulum tamamlandıktan sonra, Cypress'i ilk kez açmak için aşağıdaki komutu kullanın:


npx cypress open

Bu komut, Cypress Test Runner'ı başlatır ve projenizde otomatik olarak bir cypress/ klasörü oluşturur. Bu klasörün içinde örnek test dosyalarını ve yapılandırma dosyalarını bulacaksınız. Şimdi basit bir test yazarak, ana sayfanın başarıyla yüklendiğini ve belirli bir başlığın göründüğünü doğrulayalım. Bunun için cypress/e2e dizini altında yeni bir dosya oluşturabiliriz, örneğin home.cy.js.


describe('Ana Sayfa Testleri', () => {
  it('Ana sayfa başarıyla yüklenmeli ve başlığı doğru olmalı', () => {
    cy.visit('http://localhost:3000'); // Uygulamanızın adresini buraya yazın
    cy.title().should('eq', 'Uygulama Adı'); // Sayfa başlığını kontrol et
    cy.get('h1').should('contain', 'Hoş Geldiniz'); // H1 etiketini kontrol et
  });
});

Bu test, cy.visit() komutuyla belirtilen URL'ye gider, ardından cy.title().should('eq', ...) ile sayfa başlığını kontrol eder ve son olarak cy.get('h1').should('contain', ...) ile sayfadaki bir h1 etiketinin belirli bir metni içerip içermediğini doğrular. Bu temel adımlar, Cypress ile E2E testine başlamak için sağlam bir zemin oluşturur ve uygulamanızın temel işlevselliğinin beklendiği gibi çalıştığını doğrulamak için harika bir başlangıç noktasıdır.

Cypress Komutları ve Seçicilerle Element Etkileşimi Nasıl Sağlanır?

Cypress testlerinin kalbinde, web sayfasındaki elementlerle etkileşim kurmayı sağlayan güçlü komutlar ve seçiciler yatar. Etkili bir E2E testi yazmak için bu komutları ve seçicileri ustaca kullanmak büyük önem taşır. cy.get() komutu, DOM'dan bir veya daha fazla element seçmek için en sık kullanılan yöntemdir. CSS seçicilerini kullanarak belirli elementlere ulaşabiliriz. Örneğin, bir butona tıklamak veya bir metin giriş alanına değer yazmak için bu komutu kullanırız. Seçicilerin doğru ve dayanıklı olması, testlerinizin uygulama arayüzünde yapılan küçük değişikliklerden etkilenmemesini sağlar. Bu nedenle, mümkün olduğunca id, data-test veya data-cy gibi özel test niteliklerini kullanmak en iyi uygulamadır.

cy.get() ile bir element seçtikten sonra, bu element üzerinde çeşitli eylemler gerçekleştirmek için zincirleme komutlar kullanabiliriz. Örneğin, bir metin kutusuna yazı yazmak için .type(), bir butona tıklamak için .click() ve bir elementin görünür olduğunu doğrulamak için .should('be.visible') gibi komutlar mevcuttur. Cypress'in otomatik tekrar deneme (retryability) özelliği sayesinde, bir elementin DOM'da görünmesi veya etkileşime hazır hale gelmesi için beklemeye gerek kalmaz; Cypress bu işlemi sizin yerinize halleder. Bu, testlerin daha az yanıltıcı hatayla daha kararlı olmasını sağlar. Ayrıca, cy.contains() komutu, metin içeriğine göre elementleri bulmak için çok kullanışlıdır, özellikle dinamik içerikli sayfalarda belirli bir metni içeren bir düğmeyi veya bağlantıyı bulmak istediğinizde. Ancak dikkatli kullanılmalıdır, çünkü metin değişiklikleri testi bozabilir.

Vaka Analizi: E-ticaret Sitesi Ürün Arama Testi

Bir e-ticaret sitesinde, kullanıcıların ürün arayabildiğini test etmek için aşağıdaki adımları izleyebilirsiniz:

  1. Ana sayfayı ziyaret et.
  2. Arama kutusunu bul ve "laptop" yaz.
  3. Arama butonuna tıkla.
  4. Arama sonuçları sayfasının açıldığını ve en az bir "laptop" içeren ürünün göründüğünü doğrula.


  describe('Ürün Arama Testi', () => {
    it('Kullanıcı "laptop" aratıp sonuçları görmeli', () => {
      cy.visit('http://localhost:8080');
      cy.get('[data-cy="search-input"]').type('laptop'); // data-cy niteliği ile arama kutusunu bul
      cy.get('[data-cy="search-button"]').click(); // data-cy niteliği ile arama butonunu bul
      cy.url().should('include', '/search?q=laptop'); // URL'in değiştiğini kontrol et
      cy.get('[data-cy="product-card"]').should('have.length.at.least', 1); // En az bir ürün kartı olduğunu kontrol et
      cy.get('[data-cy="product-card"]').first().should('contain', 'Laptop'); // İlk ürün kartının "Laptop" içerdiğini kontrol et
    });
  });
  

Bu örnek, data-cy gibi özel niteliklerin testlerin dayanıklılığı için nasıl kullanılabileceğini ve zincirleme komutlarla karmaşık bir akışın nasıl test edilebileceğini göstermektedir.

Sağlam Seçiciler ve Doğrulamalar (Assertions) Nasıl Yazılır?

Sağlam Cypress testleri yazmanın anahtarı, dayanıklı ve anlamlı seçiciler kullanmaktır. ID'ler, mümkün olduğunca benzersiz oldukları için harika bir seçicidir. Ancak ID'ler her zaman mevcut olmayabilir. Bu durumda, geliştiricilerle işbirliği yaparak elementlere özel data-cy, data-test veya data-qa gibi nitelikler eklemek en iyi yaklaşımdır. Bu nitelikler, UI değişikliklerinden en az etkilenir ve testlerinizi daha sürdürülebilir hale getirir. Örneğin, bir düğmenin metni veya CSS sınıfı değişse bile, data-cy="submit-button" seçiciniz çalışmaya devam edecektir.


// Kötü örnek: sınıf adı değişirse test bozulur
cy.get('.btn-primary').click();

// Daha iyi örnek: data niteliği daha dayanıklı
cy.get('[data-cy="login-button"]').click();

Doğrulamalar (Assertions) ise testlerinizin beklentilerinizi karşılayıp karşılamadığını kontrol etmenizi sağlar. Cypress, .should() komutuyla zengin bir doğrulama kütüphanesi sunar. Bir elementin görünür olup olmadığını (be.visible), belirli bir metni içerip içermediğini (contain), bir giriş alanının belirli bir değere sahip olup olmadığını (have.value) veya CSS özelliklerini (have.css) kontrol edebilirsiniz. Birden fazla doğrulamayı aynı zincirde .and() ile birleştirebilirsiniz.


cy.get('[data-cy="username-input"]')
  .type('testuser')
  .should('have.value', 'testuser') // Değerini doğrula
  .and('be.visible'); // Görünür olduğunu doğrula

cy.get('[data-cy="error-message"]').should('not.exist'); // Hata mesajının olmaması

Bu şekilde, hem kullanıcı etkileşimlerini hem de uygulamanın bu etkileşimlere verdiği tepkileri güvenilir bir şekilde test edebilirsiniz. Unutmayın, iyi yazılmış seçiciler ve kapsamlı doğrulamalar, testlerinizin hem güvenilirliğini hem de okunabilirliğini önemli ölçüde artırır.

Test Akışını Yönetme ve Gelişmiş Senaryolar İçin Neler Kullanılır?

Büyük ve karmaşık uygulamalar için etkili E2E testleri yazmak, sadece komutları doğru kullanmaktan daha fazlasını gerektirir. Test akışınızı yönetmek, kod tekrarını azaltmak ve testlerinizi daha sürdürülebilir hale getirmek için Cypress'in sunduğu gelişmiş özellikleri kullanmak hayati önem taşır. Bu bağlamda, test yaşam döngüsü kancaları (hooks), özel komutlar (custom commands) ve Page Object Model (POM) gibi tasarım desenleri ön plana çıkar. Bu araçlar, test suite'lerinizin temiz, okunabilir ve bakımı kolay olmasını sağlar.

Test kancaları, belirli eylemleri testlerden önce veya sonra otomatik olarak çalıştırmanıza olanak tanır. Örneğin, her testten önce bir kullanıcının oturum açmasını sağlamak veya bir veritabanını temizlemek isteyebilirsiniz. before() tüm testlerden önce bir kez, beforeEach() ise her testten önce çalışır. Benzer şekilde, after() ve afterEach() kancaları da testlerin sonunda veya her testten sonra belirli eylemleri gerçekleştirmek için kullanılır. Bu sayede, test dosyalarınızda gereksiz tekrarı önler ve testlerinizin izole olmasını sağlarsınız. Her testin bağımsız bir ortamda çalışması, bir testin diğerini etkilemesini engeller ve hataların izini sürmeyi kolaylaştırır.

Uzman İpucu: Kancaları kullanırken, beforeEach() içinde oturum açma gibi sık tekrarlanan işlemleri gerçekleştirmek, her testin temiz bir başlangıç yapmasını sağlar ve test süresini optimize etmeye yardımcı olur. Ancak dikkatli olun, çok fazla işlem testleri yavaşlatabilir.

Custom Komutlar ve Page Object Model (POM) ile Testleri Yapılandırma

Cypress'te özel komutlar oluşturmak, tekrar eden test adımlarını soyutlamanın ve kod tekrarını azaltmanın harika bir yoludur. Örneğin, uygulamanızda sık sık bir kullanıcının oturum açması gerekiyorsa, bu işlemi bir özel komut olarak tanımlayabilir ve tüm testlerinizde kolayca kullanabilirsiniz. Bu, test kodunuzu daha okunabilir ve bakımı daha kolay hale getirir. Özel komutlar, cypress/support/commands.js dosyasında tanımlanır ve tüm test dosyalarınızda global olarak erişilebilir hale gelir.


// cypress/support/commands.js
Cypress.Commands.add('login', (username, password) => {
  cy.visit('/login');
  cy.get('[data-cy="username"]').type(username);
  cy.get('[data-cy="password"]').type(password);
  cy.get('[data-cy="login-button"]').click();
  cy.url().should('include', '/dashboard');
});

// Test dosyasında kullanım:
describe('Dashboard Testleri', () => {
  beforeEach(() => {
    cy.login('testuser', 'password123');
  });

  it('Kullanıcı gösterge tablosunu görmeli', () => {
    cy.get('[data-cy="welcome-message"]').should('contain', 'Hoş Geldiniz, testuser');
  });
});

Page Object Model (POM), büyük ölçekli E2E test projelerinde yaygın olarak kullanılan bir tasarım desenidir. POM ile, uygulamanızdaki her sayfa veya ana bileşen için bir "sayfa nesnesi" oluşturursunuz. Bu sayfa nesnesi, ilgili sayfanın UI elementlerini (seçiciler) ve bu elementlerle yapılabilecek etkileşimleri (metodlar) kapsüller. Bu yaklaşım, UI değişiklikleri olduğunda yalnızca ilgili sayfa nesnesini güncellemeniz gerektiği anlamına gelir, böylece birçok test dosyasında değişiklik yapmaktan kurtulursunuz. Test kodunuz daha temiz, daha okunaklı ve daha sürdürülebilir hale gelir.


// cypress/pages/LoginPage.js
class LoginPage {
  get usernameInput() { return cy.get('[data-cy="username"]'); }
  get passwordInput() { return cy.get('[data-cy="password"]'); }
  get loginButton() { return cy.get('[data-cy="login-button"]'); }

  visit() {
    cy.visit('/login');
  }

  login(username, password) {
    this.usernameInput.type(username);
    this.passwordInput.type(password);
    this.loginButton.click();
  }
}
export default new LoginPage();

// Test dosyasında kullanım:
import LoginPage from '../pages/LoginPage';

describe('Login Testleri - POM', () => {
  it('Kullanıcı başarıyla giriş yapmalı', () => {
    LoginPage.visit();
    LoginPage.login('testuser', 'password123');
    cy.url().should('include', '/dashboard');
  });
});

Bu yapı, testlerinizin karmaşıklığını azaltır ve büyük projelerde bile düzenli kalmasını sağlar. Ayrıca, testlerinizi daha modüler hale getirerek tekrar kullanılabilirliği artırır.

Ağ İsteklerini ve Sunucu Yanıtlarını Nasıl Kontrol Edebiliriz?

Uçtan uca testlerde, uygulamanızın arka uç (backend) ile nasıl iletişim kurduğunu anlamak ve bu iletişimi manipüle etmek kritik öneme sahiptir. Cypress, cy.intercept() komutu aracılığıyla ağ isteklerini izleme, engelleme ve hatta sahte (mock) yanıtlar döndürme yeteneği sunarak bu konuda benzersiz bir güç sağlar. Bu özellik, özellikle karmaşık API bağımlılıkları olan uygulamaları test ederken veya belirli sunucu yanıtlarını simüle etmek istediğinizde inanılmaz derecede faydalıdır. cy.intercept() ile, API testlerini, UI testlerinden izole bir şekilde gerçekleştirebilir ve böylece testlerinizin daha hızlı ve daha kararlı olmasını sağlayabilirsiniz.

Bir uygulamanın kullanıcı arayüzü ile arka ucu arasındaki etkileşimi test etmek, çoğu zaman bir API çağrısının başarılı bir şekilde yapıldığını ve doğru verilerin döndüğünü doğrulamayı gerektirir. cy.intercept() ile belirli bir URL'ye yapılan istekleri yakalayabilir, bu isteklerin içeriğini kontrol edebilir ve hatta bu isteklere özel yanıtlar döndürebilirsiniz. Örneğin, bir liste sayfasının yüklendiğini test ederken, sunucudan beklenen veri gelene kadar bekleyebilir veya sunucu hatası durumunu simüle edebilirsiniz. Bu, hata durumlarının kullanıcı arayüzünde doğru bir şekilde işlendiğini doğrulamak için harika bir yoldur. Ayrıca, harici üçüncü taraf API'larına yapılan istekleri engellemek veya onlara sahte yanıtlar vermek, testlerinizin dış bağımlılıklardan arındırılmasını sağlar, bu da testlerin daha hızlı ve güvenilir çalışmasına katkıda bulunur.

Vaka Analizi: Kullanıcı Listesi Yükleme ve Hata Durumu Testi

Bir uygulamanın kullanıcı listesini görüntülediği bir sayfa olduğunu varsayalım. Bu sayfada:

  1. Kullanıcı listesinin başarılı bir şekilde yüklendiğini test etme.
  2. Sunucudan bir hata gelmesi durumunda, hata mesajının doğru görüntülendiğini test etme.


  // Başarılı Yükleme Senaryosu
  describe('Kullanıcı Listesi - Başarılı', () => {
    it('Kullanıcı listesi başarıyla yüklenmeli', () => {
      cy.intercept('GET', '/api/users', {
        statusCode: 200,
        body: [
          { id: 1, name: 'Alice' },
          { id: 2, name: 'Bob' }
        ]
      }).as('getUsers'); // İsteği alias ile kaydet

      cy.visit('/users');
      cy.wait('@getUsers'); // İsteğin tamamlanmasını bekle
      cy.get('[data-cy="user-list-item"]').should('have.length', 2);
      cy.get('[data-cy="user-list-item"]').first().should('contain', 'Alice');
    });
  });

  // Hata Durumu Senaryosu
  describe('Kullanıcı Listesi - Hata', () => {
    it('API hatası durumunda hata mesajı gösterilmeli', () => {
      cy.intercept('GET', '/api/users', {
        statusCode: 500,
        body: { message: 'Sunucu Hatası' }
      }).as('getUsersError');

      cy.visit('/users');
      cy.wait('@getUsersError');
      cy.get('[data-cy="error-message"]').should('be.visible').and('contain', 'Sunucu Hatası');
    });
  });
  

Bu örnekler, cy.intercept() ile hem başarılı hem de hatalı API yanıtlarını nasıl simüle edebileceğimizi ve cy.wait() kullanarak bu isteklerin tamamlanmasını nasıl bekleyebileceğimizi göstermektedir. Bu sayede, uygulamanızın farklı sunucu yanıtlarına nasıl tepki verdiğini kapsamlı bir şekilde test edebilirsiniz.

Asenkron İşlemleri ve Beklemeleri Yönetme

Web uygulamaları doğası gereği asenkrondur. Veri yüklemeleri, animasyonlar veya kullanıcı etkileşimlerinden sonra gerçekleşen DOM güncellemeleri gibi işlemler, testlerde gecikmelere yol açabilir. Cypress, bu asenkron yapıyı yönetmek için güçlü mekanizmalar sunar. cy.wait() komutu, belirli bir ağ isteğinin tamamlanmasını beklemek veya belirli bir süre duraklamak için kullanılır. Özellikle cy.intercept() ile birlikte kullanıldığında, API yanıtlarının test akışınızı etkilememesi sağlanır.


cy.intercept('POST', '/api/submit-form').as('submitForm'); // Bir POST isteğini yakala
cy.get('[data-cy="submit-button"]').click();
cy.wait('@submitForm').its('response.statusCode').should('eq', 200); // İsteğin tamamlanmasını ve durum kodunu doğrula

Ancak, cy.wait()'ı sabit sürelerle (cy.wait(2000) gibi) kullanmaktan kaçınmak önemlidir, çünkü bu testleri yavaşlatabilir ve "flaky" (kararsız) testlere yol açabilir. Bunun yerine, Cypress'in yerleşik tekrar deneme mekanizmalarına güvenmek veya belirli bir elementin görünmesini ya da kaybolmasını beklemek için .should('be.visible') veya .should('not.exist') gibi doğrulamaları kullanmak daha iyi bir yaklaşımdır. Cypress, bir elementin DOM'da görünmesini beklerken otomatik olarak yeniden dener, bu da testlerinizin daha kararlı ve hızlı olmasını sağlar. Bu özellik, özellikle dinamik içerikli sayfalarda veya yavaş API yanıtları olan durumlarda testlerin başarısız olma olasılığını büyük ölçüde azaltır.

Cypress ile Performans ve Hata Ayıklama Stratejileri Nelerdir?

Etkin bir E2E test suite'i oluşturmak, sadece testleri yazmaktan ibaret değildir; aynı zamanda bu testlerin performansını optimize etmek ve gerektiğinde kolayca hata ayıklayabilmek de büyük önem taşır. Cypress, bu konularda geliştiricilere yardımcı olacak bir dizi araç ve özellik sunar. Hızlı çalışan ve kararlı testler, geliştirme sürecini hızlandırırken, kolay hata ayıklama özellikleri de sorunları hızla tespit edip çözmenizi sağlar. Bu bölümde, Cypress ile test performansınızı artırmanın ve hata ayıklama sürecinizi kolaylaştırmanın yollarını keşfedeceğiz.

Cypress Test Runner, testlerinizin her adımını görsel olarak takip etmenizi sağlayan mükemmel bir hata ayıklama aracıdır. Zaman yolculuğu (Time Travel) özelliği sayesinde, test adımları arasında ileri geri giderek uygulamanın o anki durumunu (DOM snapshot'lar, ağ istekleri, konsol çıktıları) inceleyebilirsiniz. Bu, bir hatanın tam olarak nerede ve neden meydana geldiğini anlamak için paha biçilmezdir. Ayrıca, cy.pause() komutunu kullanarak test yürütmeyi belirli bir noktada duraklatabilir ve tarayıcının geliştirici araçlarını kullanarak DOM'u manuel olarak inceleyebilirsiniz. Bu, özellikle karmaşık etkileşimlerde veya beklenmedik durumlarla karşılaştığınızda çok işinize yarar. cy.debug() komutu ise, belirli bir Cypress komutuyla ilgili bilgileri doğrudan tarayıcı konsoluna yazdırarak daha detaylı hata ayıklama imkanı sunar.

Uzman İpucu: Testlerinizi CI/CD ortamında çalıştırırken Cypress Dashboard'u kullanmak, test geçmişinizi, hataları ve performans metriklerini merkezi bir yerden takip etmenizi sağlar. Bu, takım çalışmasında ve büyük projelerde izlenebilirlik için kritik öneme sahiptir.

Testleri Hızlandırma ve Stabiliteyi Artırma Yöntemleri

Test süitinizin büyümesiyle birlikte test süreleri de uzayabilir. Testleri hızlandırmak için çeşitli stratejiler mevcuttur. İlk olarak, veritabanı temizleme ve test verisi oluşturma gibi ön hazırlık işlemlerini before() veya beforeEach() kancalarında verimli bir şekilde yapın. Mümkünse, API'ları taklit (mock) ederek veya stublayarak dış bağımlılıkları azaltın, bu da testlerin daha hızlı ve daha az "flaky" olmasını sağlar. cy.intercept() bu konuda size büyük yardımcı olacaktır.


// fixtures/userData.json
// [{ "id": 1, "name": "Test User" }]

// Test dosyasında:
beforeEach(() => {
  cy.intercept('GET', '/api/users', { fixture: 'userData.json' }).as('getUsers');
  cy.visit('/users');
  cy.wait('@getUsers');
});

Testleriniz arasındaki bağımlılıkları azaltmak da önemlidir. Her testin bağımsız olması, bir testin başarısızlığının diğerlerini etkilemesini engeller ve paralelleştirmeyi kolaylaştırır. Cypress Dashboard'un paralelleştirme özelliği, testleri birden fazla makinede aynı anda çalıştırarak toplam test süresini önemli ölçüde kısaltabilir. Ayrıca, gereksiz DOM etkileşimlerinden kaçınmak ve sadece kritik adımları test etmek de performansı artırır. Örneğin, bir elementin görünür olduğunu test etmek için sürekli animasyonların bitmesini beklemek yerine, element DOM'a eklendiğinde doğrudan doğrulamak daha hızlıdır. Testlerinizin mobil cihazlarda doğru çalıştığını doğrulamak için cy.viewport() komutunu kullanarak farklı ekran boyutlarını test edebilirsiniz, ancak bu performansı değil, uyumluluğu kontrol eder.


// Mobil uyumluluğu test etme
describe('Mobil Cihazda Duyarlı Tasarım', () => {
  it('Sidebar mobil görünümde gizlenmeli', () => {
    cy.viewport('iphone-6'); // iPhone 6 boyutlarına ayarla
    cy.visit('/');
    cy.get('[data-cy="sidebar"]').should('not.be.visible'); // Sidebar'ın görünür olmadığını kontrol et
  });
});

Bu gibi stratejiler, Cypress test süitinizin hem hızlı hem de güvenilir olmasını sağlayarak geliştirme sürecinize değerli katkılar sunar.

Gerçek Dünya Uygulamalarında Cypress'in Gücü: Vaka Analizleri

Teorik bilgileri pekiştirmenin en iyi yolu, onları gerçek dünya senaryolarına uygulamaktır. Cypress, karmaşık web uygulamalarını test etmek için tasarlanmış bir araç olduğundan, çeşitli senaryolarda nasıl kullanılabileceğini görmek, bilginizi pekiştirmenize yardımcı olacaktır. Bu bölümde, sık karşılaşılan üç farklı vaka analizi üzerinden Cypress'in gücünü ve esnekliğini inceleyeceğiz: bir kullanıcı giriş/çıkış akışı, bir form doldurma ve doğrulama süreci ve dinamik bir Tek Sayfa Uygulaması (SPA) üzerindeki etkileşimler. Bu örnekler, daha önce öğrendiğimiz temel komutların ve ileri düzey tekniklerin pratikte nasıl bir araya getirildiğini gösterecektir.

İlk vaka analizimiz, bir kullanıcının başarılı bir şekilde oturum açıp ardından oturumu kapatmasını içeren tipik bir kimlik doğrulama akışıdır. Bu senaryo, cy.visit(), .type(), .click() gibi temel komutların yanı sıra, cy.url().should('include', ...) ve cy.get(...).should('not.exist') gibi doğrulamaları kullanarak uygulamanın beklenen durumlara geçişini kontrol etmeyi içerir. Özellikle oturum açma işlemi, beforeEach kancası veya özel bir cy.login() komutu aracılığıyla tekrar kullanılabilir hale getirilerek testlerin daha DRY (Don't Repeat Yourself) olmasını sağlar. Bu sayede, diğer testlerde de oturum açma işlevselliğini kolayca kullanabiliriz.

Vaka Analizi 1: Kullanıcı Giriş/Çıkış Akışı

Bir web uygulamasına giriş yapıp ardından çıkış yapma senaryosu:

  1. Giriş sayfasına git.
  2. Geçerli kullanıcı adı ve şifre ile giriş yap.
  3. Ana sayfanın yüklendiğini doğrula.
  4. Çıkış butonuna tıkla.
  5. Giriş sayfasına geri dönüldüğünü doğrula.


  describe('Kullanıcı Giriş/Çıkış Akışı', () => {
    it('Kullanıcı başarıyla giriş yapmalı ve çıkış yapmalı', () => {
      cy.visit('/login');
      cy.get('[data-cy="username-input"]').type('validuser');
      cy.get('[data-cy="password-input"]').type('validpassword');
      cy.get('[data-cy="login-button"]').click();
      cy.url().should('include', '/dashboard'); // Giriş sonrası dashboard'a yönlendirme

      cy.get('[data-cy="logout-button"]').click();
      cy.url().should('include', '/login'); // Çıkış sonrası login sayfasına yönlendirme
      cy.get('[data-cy="username-input"]').should('be.visible'); // Login sayfasının görünür olduğunu doğrula
    });
  });
  

Dinamik Form Testleri ve SPA Uygulamalarında Gezinme

İkinci vaka analizimiz, kullanıcıların karmaşık bir formu doldurup gönderebildiğini ve form doğrulama kurallarının doğru çalıştığını test etmektir. Bu senaryo, metin girişleri, seçim kutuları (.select()), onay kutuları (.check()/.uncheck()) gibi farklı form elementleriyle etkileşimleri ve gönderim sonrası başarılı/başarısız mesajlarını kontrol etmeyi içerir. cy.intercept() kullanarak form gönderiminin API tarafındaki yanıtını taklit etmek, testlerin hızlı ve izole bir şekilde çalışmasını sağlar.

Vaka Analizi 2: Kayıt Formu Doldurma ve Doğrulama

Yeni bir kullanıcı kayıt formunun doğru çalıştığını test etme:

  1. Kayıt sayfasına git.
  2. Tüm gerekli alanları doldur.
  3. Hüküm ve koşulları kabul et.
  4. Formu gönder.
  5. Başarılı kayıt mesajının göründüğünü doğrula.
  6. Hata senaryosunu test etmek için eksik veya yanlış veri girişi yaparak hata mesajlarının görüntülendiğini doğrula.


  describe('Kayıt Formu Testleri', () => {
    beforeEach(() => {
      cy.visit('/register');
      cy.intercept('POST', '/api/register').as('registerUser');
    });

    it('Geçerli bilgilerle kayıt başarılı olmalı', () => {
      cy.get('[data-cy="name-input"]').type('Test User');
      cy.get('[data-cy="email-input"]').type('test@example.com');
      cy.get('[data-cy="password-input"]').type('Password123!');
      cy.get('[data-cy="confirm-password-input"]').type('Password123!');
      cy.get('[data-cy="terms-checkbox"]').check(); // Checkbox'ı işaretle
      cy.get('[data-cy="submit-button"]').click();

      cy.wait('@registerUser').its('response.statusCode').should('eq', 201);
      cy.get('[data-cy="success-message"]').should('be.visible').and('contain', 'Kayıt başarılı!');
    });

    it('Eksik email ile kayıt başarısız olmalı', () => {
      cy.get('[data-cy="name-input"]').type('Test User');
      cy.get('[data-cy="password-input"]').type('Password123!');
      cy.get('[data-cy="confirm-password-input"]').type('Password123!');
      cy.get('[data-cy="terms-checkbox"]').check();
      cy.get('[data-cy="submit-button"]').click();

      cy.get('[data-cy="email-error"]').should('be.visible').and('contain', 'E-posta alanı zorunludur.');
    });
  });
  

Üçüncü vaka analizimiz, modern bir Tek Sayfa Uygulamasında (SPA) gezinme ve dinamik içerik yükleme senaryolarını kapsar. SPA'lar, geleneksel çok sayfalı uygulamalardan farklı olarak, sayfa yenilenmeden içerik yükledikleri ve rotaları değiştirdikleri için özel bir test yaklaşımı gerektirebilir. Cypress, bu dinamik yapıyı sorunsuz bir şekilde ele alır. Router geçişlerini, asenkron veri yüklemelerini ve UI güncellemelerini test ederken, cy.wait() ve cy.intercept() komutları büyük önem taşır. Bu sayede, uygulamanızın farklı rotalara doğru bir şekilde geçiş yaptığını ve içeriklerin beklendiği gibi yüklendiğini doğrulayabilirsiniz. Bu vaka analizleri, Cypress'in farklı ve karmaşık test senaryolarında nasıl etkin bir şekilde kullanılabileceğini açıkça göstermektedir, böylece geliştiriciler daha güvenilir ve bakımı kolay testler yazabilirler.


describe('SPA Gezinme Testleri', () => {
  it('Anasayfadan ürün detayına gidilmeli ve ürün bilgileri doğru yüklenmeli', () => {
    cy.intercept('GET', '/api/products/123', {
      statusCode: 200,
      body: { id: 123, name: 'Örnek Ürün', price: 99.99 }
    }).as('getProductDetail');

    cy.visit('/');
    cy.get('[data-cy="product-card-123"]').click(); // Ana sayfadaki bir ürün kartına tıkla
    cy.url().should('include', '/products/123'); // URL'in değiştiğini doğrula
    cy.wait('@getProductDetail'); // Ürün detayı API isteğinin tamamlanmasını bekle
    cy.get('[data-cy="product-name"]').should('contain', 'Örnek Ürün');
    cy.get('[data-cy="product-price"]').should('contain', '99.99');
  });
});

Sonuç: Cypress ile Etkin E2E Test Uzmanlığına Doğru

Bu makale boyunca, Cypress'in uçtan uca testlerde neden vazgeçilmez bir araç olduğunu, temel komutlarından gelişmiş özelliklerine kadar birçok teknik konuyu derinlemesine inceledik. Modern web uygulamalarının karmaşıklığı karşısında, Cypress'in tarayıcı içi çalışma prensibi, otomatik tekrar deneme yeteneği ve zengin hata ayıklama özellikleri, geliştiricilere ve QA mühendislerine eşsiz bir avantaj sağlamaktadır. Komutları ve seçicileri ustaca kullanarak kullanıcı etkileşimlerini simüle etmek, cy.intercept() ile ağ isteklerini kontrol altına almak, test akışını kancalar ve özel komutlarla yönetmek, ve Page Object Model gibi tasarım desenleriyle testleri yapılandırmak, Cypress'te uzmanlaşmanın temel taşlarıdır. Ayrıca, performans optimizasyonu ve etkili hata ayıklama stratejileri, test süitlerinizin sürdürülebilirliğini ve güvenilirliğini artırmak için kritik öneme sahiptir.

Cypress'i etkili bir şekilde kullanmak, sadece kod yazmakla kalmaz, aynı zamanda test edilebilir kod yazma alışkanlığı kazanmayı ve uygulamanızın mimarisini testlerinizi destekleyecek şekilde düşünmeyi de gerektirir. Gerçek dünya vaka analizleri, öğrendiğimiz teorik bilgileri pratiğe dökme konusunda size yol gösterdi. Bu sayede, giriş/çıkış akışlarından karmaşık form doğrulamalarına ve SPA gezinmelerine kadar çeşitli senaryoları nasıl güvenle test edebileceğinizi gördünüz. Cypress öğrenme yolculuğunuz, bu teknik konulara hakim oldukça daha da verimli hale gelecektir. Unutmayın, iyi yazılmış E2E testleri, hem geliştirme sürecini hızlandırır hem de son kullanıcıya sunulan ürünün kalitesini güvence altına alır.

Sıkça Sorulan Sorular (SSS)

Cypress, Selenium veya Playwright'tan farkı nedir?
Cypress, tarayıcı içinde doğrudan çalışan, otomatik tekrar deneme yeteneğine sahip ve entegre bir geliştirici deneyimi sunan bir araçtır. Selenium ve Playwright gibi WebDriver tabanlı araçlar tarayıcı dışından iletişim kurarken, Cypress bu gecikmeyi ortadan kaldırır. Bu sayede Cypress, daha hızlı test yürütme ve daha kolay hata ayıklama sunar, ancak çapraz tarayıcı desteği (şu an için) diğerleri kadar geniş değildir.
Cypress ile tüm test türlerini (birim, entegrasyon, E2E) yapabilir miyim?
Cypress öncelikle E2E testleri için tasarlanmıştır, ancak Component Testing özelliği ile modern UI kütüphaneleri (React, Vue, Angular) için birim ve entegrasyon testlerini de destekler. Geleneksel backend birim testleri için uygun değildir, ancak API testlerini E2E akışının bir parçası olarak veya doğrudan cy.request() ile yapabilirsiniz.
Cypress testlerimi CI/CD ortamına nasıl entegre edebilirim?
Cypress testleri, çeşitli CI/CD platformlarıyla (Jenkins, GitHub Actions, GitLab CI, CircleCI vb.) kolayca entegre edilebilir. cypress run komutuyla testleri başsız (headless) modda çalıştırabilir ve test sonuçlarını Cypress Dashboard'a gönderebilirsiniz. Bu, testlerin otomatikleştirilmesi ve geliştirme hattına sorunsuz bir şekilde dahil edilmesi için kritik öneme sahiptir.
Cypress testlerimi daha hızlı hale getirmek için neler yapabilirim?
Testleri hızlandırmak için: API'ları cy.intercept() ile taklit edin (mock), gereksiz cy.wait() kullanmaktan kaçının, testleri küçültün ve bağımsız hale getirin, ve Cypress Dashboard'un paralelleştirme özelliğini kullanarak testleri aynı anda farklı makinelerde çalıştırın. Ayrıca, test öncesi veritabanı temizliği ve test verisi hazırlığı gibi işlemleri optimize edin.
Cypress testlerinde responsive (duyarlı) tasarımı nasıl test edebilirim?
cy.viewport() komutunu kullanarak test ortamının ekran boyutunu dinamik olarak değiştirebilirsiniz. Bu sayede, farklı cihaz boyutlarında uygulamanızın nasıl göründüğünü ve davrandığını test edebilirsiniz. Örneğin, cy.viewport('iphone-x') veya cy.viewport(1280, 720) ile belirli çözünürlükleri simüle edebilirsiniz.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.