Cypress Mimari Tasarım: 10 Best Practice [2026 Kapsamlı Rehber]
Yazar: Burak Balkı | Kategori: Cloud Computing | Okuma Süresi: 39 dk
Bu rehber, 2026 güncel yaklaşımlarla Cypress mimari tasarım prensiplerini, ileri seviye tekniklerini ve best practice'lerini detaylı örneklerle sunar. Hızlı,...
### Giriş: 2026'da Test Otomasyonunun Yükselen Yıldızı Cypress
2026 yılı itibarıyla yazılım geliştirme süreçlerinde kalite güvencesi her zamankinden daha kritik bir öneme sahip. Hızlı teslimat döngüleri ve artan kullanıcı beklentileri, sağlam ve sürdürülebilir test otomasyonu mimarilerini zorunlu kılıyor. Son projemde, karmaşık bir mikroservis mimarisinde uçtan uca testleri yönetirken karşılaştığım en büyük zorluk, test süitlerinin bakımı ve performans optimizasyonuydu. Bu noktada **Cypress**'in sunduğu mimari esneklik ve geliştirici dostu yaklaşım, ekibimizin %35 daha hızlı geri bildirim almasını sağladı. Bu kapsamlı rehberde, 2026'nın en güncel yaklaşımlarıyla Cypress'in mimari tasarım prensiplerini, ileri seviye tekniklerini ve en iyi pratiklerini detaylı örneklerle inceleyeceğiz. Yazılım kalitenizi bir üst seviyeye taşımak için bu rehberi mutlaka okuyun.
## Cypress Nedir?
Cypress, modern web uygulamaları için geliştirilmiş, hızlı, güvenilir ve geliştirici dostu bir uçtan uca (end-to-end) test otomasyon aracıdır. Tarayıcıda doğrudan çalışan yapısı sayesinde testlerinizi gerçek kullanıcı deneyimine en yakın şekilde simüle eder, böylece hataları erken aşamada yakalamanızı sağlar. Cypress, özellikle tek sayfa uygulamaları (SPA) ve karmaşık kullanıcı arayüzleri (UI) için idealdir, geliştiricilere anında geri bildirim sunarak test yazma ve hata ayıklama süreçlerini basitleştirir. Kimler kullanır derseniz, JavaScript/TypeScript ekosisteminde çalışan tüm frontend ve full-stack geliştiriciler ile QA mühendisleri için vazgeçilmez bir araç haline gelmiştir.
Cypress, Node.js tabanlı olup, tarayıcıda doğrudan testleri çalıştırır. Bu mimari, testlerin uygulamanızla aynı run loop'ta çalışmasını sağlayarak, dış süreçlerle iletişim kurma zorunluluğunu ortadan kaldırır. Geleneksel Selenium tabanlı araçların aksine, Cypress doğrudan DOM'a erişebilir, ağ isteklerini izleyebilir ve hatta tarayıcı olaylarını manipüle edebilir. Bu sayede testler daha hızlı, daha kararlı ve daha güvenilir hale gelir. Cypress'in 2026 itibarıyla en güncel kararlı sürümü olan 14.x, geliştiricilere daha da gelişmiş hata ayıklama yetenekleri, daha iyi performans ve genişletilmiş entegrasyon seçenekleri sunmaktadır. Cypress'in resmi dökümantasyonuna [Cypress Resmi Dokümantasyonu](https://docs.cypress.io/) adresinden ulaşabilirsiniz.
## Neden Cypress Kullanmalısınız?
Cypress, test otomasyon dünyasında kendine sağlam bir yer edinmiş durumda. Peki, 2026'da projelerinizde neden Cypress'i tercih etmelisiniz? İşte somut faydaları ve çözüm sunduğu problemler:
* **Hızlı ve Güvenilir Testler:** Cypress, testleri tarayıcı içinde çalıştırarak Selenium gibi araçların dış süreç iletişim maliyetini ortadan kaldırır. Bu sayede testleriniz daha hızlı koşar ve flaky (dengesiz) testlerin oranı önemli ölçüde azalır. Production ortamında karşılaştığım en yaygın sorunlardan biri olan testlerin zaman zaman sebepsiz yere başarısız olması, Cypress ile büyük ölçüde çözüme kavuştu.
* **Geliştirici Dostu Deneyim:** JavaScript/TypeScript ile yazılması, mevcut frontend geliştiricilerinin hızlıca adapte olmasını sağlar. Güçlü hata ayıklama araçları, otomatik yeniden yükleme (auto-reloading) ve zaman yolculuğu (time-travel debugging) özellikleri, test yazma ve hata ayıklama sürecini keyifli hale getirir.
* **Kapsamlı Fonksiyonellik:** Uçtan uca testlerin yanı sıra, Cypress 14.x ile birlikte Component Testing ve API Testing gibi yetenekler de sunulmaktadır. Bu, tek bir araçla farklı test seviyelerini kapsayabileceğiniz anlamına gelir, test piramidinizi daha verimli bir şekilde uygulamanızı sağlar.
* **Otomatik Beklemeler (Automatic Waiting):** Cypress, elementlerin DOM'a yüklenmesini veya animasyonların tamamlanmasını otomatik olarak bekler. Bu, manuel bekleme (wait) komutlarının karmaşıklığını ortadan kaldırır ve testlerinizi daha kararlı hale getirir.
* **Aktif ve Geniş Topluluk:** Cypress, GitHub'da popülerliğini koruyan, aktif bir topluluğa sahiptir. Bu, sorunlarınıza hızlı çözümler bulabileceğiniz, yeni plugin'ler ve kaynaklar keşfedebileceğiniz anlamına gelir. Geniş ekosistemi sayesinde birçok entegrasyon ve araç desteği mevcuttur.
**Kimler için uygun:** Hızlı geliştirme döngülerine sahip, modern JavaScript/TypeScript tabanlı web uygulamaları geliştiren ekipler için idealdir. Özellikle SPA'lar, React, Angular, Vue gibi framework'lerle çalışan projelerde yüksek verimlilik sağlar.
**Kimler için uygun değil:** Eğer uygulamanızın tarayıcı dışındaki masaüstü veya mobil native özelliklerini test etmeniz gerekiyorsa veya aynı anda birden fazla tarayıcıda paralel testler yapmak sizin için kritikse, Cypress'in bazı sınırlamaları olabilir (ancak bu sınırlamalar sürekli gelişmektedir). Örneğin, Safari desteği 2026 itibarıyla hala deneysel aşamadadır.
## Cypress vs Alternatifler
Cypress, test otomasyon pazarında güçlü bir oyuncu olsa da, farklı ihtiyaçlara yönelik alternatifler de bulunmaktadır. İşte Cypress'i diğer popüler araçlarla karşılaştıran bir tablo:
| Özellik | Cypress (14.x, 2026) | Playwright (1.x, 2026) | Selenium WebDriver (4.x, 2026) |
| :----------------- | :---------------------------------------------------- | :--------------------------------------------------- | :--------------------------------------------------- |
| **Performans** | Tarayıcı içi çalışma, hızlı ve kararlı testler | Çapraz tarayıcı desteği, hızlı | Tarayıcılar arası köprüler nedeniyle daha yavaş |
| **Öğrenme Eğrisi** | JavaScript/TypeScript bilgisi yeterli, geliştirici dostu | JavaScript, Python, Java, C#, geliştirici dostu | Çeşitli diller, daha karmaşık API, yüksek öğrenme eğrisi |
| **Ekosistem** | Zengin plugin'ler, aktif topluluk, entegre araçlar | Microsoft destekli, hızla büyüyen plugin ekosistemi | Çok geniş, uzun süredir var olan, olgun |
| **Topluluk** | Çok aktif ve destekleyici | Hızla büyüyen, Microsoft desteğiyle güçlü | En büyük ve en olgun topluluk |
| **Kurumsal Destek**| Ticari destek ve danışmanlık hizmetleri mevcut | Microsoft tarafından aktif destek | Bağımsız sağlayıcılar ve topluluk desteği |
| **Kullanım Alanı** | E2E, Component, API testleri, modern web uygulamaları | E2E, Component, API testleri, çoklu tarayıcı, mobil | E2E, tarayıcı otomasyonu, eski ve yeni web uygulamaları |
**Yorum:** 2026 itibarıyla Cypress, geliştirici deneyimi ve test kararlılığı açısından hala zirvede. Ancak Playwright, çoklu tarayıcı ve platform desteğiyle ciddi bir rakip haline geldi. Selenium ise daha geniş tarayıcı ve dil desteği sunsa da, genellikle daha yüksek bakım maliyetleri ve daha karmaşık kurulum süreçleri gerektirir. Ekibiniz JavaScript/TypeScript odaklıysa ve modern web uygulamalarına odaklanıyorsa, Cypress genellikle en verimli çözümü sunar.
## Kurulum ve İlk Adımlar
Cypress'i projenize dahil etmek oldukça basittir. İşte 2026 güncel adımlarla kurulum ve ilk testinizi çalıştırma rehberi:
**Ön Gereksinimler:**
* Node.js (v16 veya üzeri önerilir)
* npm veya Yarn
* Bir web projesi (React, Angular, Vue veya herhangi bir HTML/JS uygulaması olabilir)
1. **Projenizi Başlatın ve Cypress'i Kurun:**
Projenizin ana dizininde aşağıdaki komutu çalıştırarak Cypress'i geliştirme bağımlılığı olarak kurun:
```bash
# npm ile
npm install cypress --save-dev
# veya yarn ile
yarn add cypress --dev
```
2. **Cypress'i Açın ve Yapılandırmayı Başlatın:**
Kurulum tamamlandıktan sonra, Cypress test runner'ı başlatmak için aşağıdaki komutu kullanın:
```bash
npx cypress open
```
Bu komut, Cypress uygulamasını açacak ve size `E2E Testing` veya `Component Testing` seçeneklerini sunacaktır. `E2E Testing`'i seçerek devam edin. Cypress, gerekli yapılandırma dosyalarını (`cypress.config.js`, `cypress/support`, `cypress/e2e` vb.) otomatik olarak oluşturacaktır. Size örnek testler sunacak, onları da çalıştırabilirsiniz.
3. **İlk Test Dosyanızı Oluşturun:**
`cypress/e2e` klasörünün altında yeni bir `.cy.js` veya `.cy.ts` uzantılı dosya oluşturun. Örneğin, `cypress/e2e/ilk-testim.cy.js`.
```javascript
// cypress/e2e/ilk-testim.cy.js
describe('İlk Cypress Testim', () => {
it('Ana sayfayı ziyaret eder ve başlığı kontrol eder', () => {
cy.visit('http://localhost:3000'); // Kendi uygulamanızın adresini girin
cy.contains('Hoş Geldiniz'); // Ana sayfada 'Hoş Geldiniz' metnini ara
cy.title().should('include', 'Uygulamam'); // Sayfa başlığında 'Uygulamam' geçmeli
});
});
```
4. **Testinizi Çalıştırın:**
`npx cypress open` komutunu tekrar çalıştırın ve `E2E Testing` bölümünde oluşturduğunuz `ilk-testim.cy.js` dosyasını seçerek testinizi çalıştırın. Test runner, tarayıcıyı açacak ve adımları otomatik olarak gerçekleştirecektir. Eğer uygulamanız `localhost:3000`'de çalışmıyorsa, `cy.visit()` içindeki URL'i doğru şekilde güncellemeyi unutmayın.
> **Pro Tip:** Cypress'in otomatik yapılandırma özelliği, yeni başlayanlar için harika bir başlangıç noktasıdır. Ancak kurumsal projelerde `cypress.config.js` dosyasını daha detaylı özelleştirmek, CI/CD entegrasyonları için kritik öneme sahiptir.
## Temel Kullanım ve Örnekler
Cypress'in temel komutları ve selektörleri ile etkileşimli testler yazmak oldukça sezgiseldir. İşte sıkça karşılaşılan senaryolar için bazı pratik örnekler:
### Örnek 1: Form Doldurma ve Gönderme
**Problem:** Bir login formunu doldurup göndermek ve başarılı bir giriş mesajını doğrulamak.
**Çözüm:** `cy.get()` ile elementleri seçip, `type()` ile veri girişi ve `click()` ile buton tıklaması yaparız.
```javascript
// cypress/e2e/login.cy.js
describe('Login Testleri', () => {
beforeEach(() => {
cy.visit('/login'); // Uygulamanızın login sayfasını ziyaret edin
});
it('Geçerli kimlik bilgileriyle giriş yapar', () => {
cy.get('input[name="username"]').type('testuser');
cy.get('input[name="password"]').type('password123');
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard'); // Yönlendirmenin doğru olduğunu kontrol et
cy.contains('Hoş Geldiniz, testuser!').should('be.visible'); // Başarı mesajını kontrol et
});
it('Geçersiz kimlik bilgileriyle giriş yapmaya çalışır', () => {
cy.get('input[name="username"]').type('wronguser');
cy.get('input[name="password"]').type('wrongpass');
cy.get('button[type="submit"]').click();
cy.contains('Geçersiz kullanıcı adı veya şifre.').should('be.visible'); // Hata mesajını kontrol et
cy.url().should('include', '/login'); // Sayfanın değişmediğini kontrol et
});
});
```
### Örnek 2: API İsteklerini Dinleme ve Mocklama
**Problem:** Frontend'in backend API'sine yaptığı bir isteği dinlemek ve yanıtını doğrulamak veya sahte (mock) bir yanıtla test etmek.
**Çözüm:** `cy.intercept()` komutu ile ağ isteklerini kontrol edebiliriz.
```javascript
// cypress/e2e/api-interception.cy.js
describe('API İsteklerini Yönetme', () => {
it('Kullanıcı listesi API isteğini dinler ve doğrular', () => {
cy.intercept('GET', '/api/users').as('getUsers'); // /api/users GET isteğini dinle
cy.visit('/users'); // Kullanıcı listesi sayfasını ziyaret et
cy.wait('@getUsers').then((interception) => {
expect(interception.response.statusCode).to.eq(200);
expect(interception.response.body).to.have.length.above(0);
expect(interception.response.body[0]).to.have.property('name');
});
cy.contains('Kullanıcılar Listesi').should('be.visible');
});
it('API isteğini mocklayarak hata durumunu simüle eder', () => {
cy.intercept('GET', '/api/users', {
statusCode: 500,
body: { message: 'Sunucu hatası oluştu.' },
}).as('getUsersError');
cy.visit('/users');
cy.wait('@getUsersError');
cy.contains('Sunucu hatası oluştu.').should('be.visible');
});
});
```
### Örnek 3: Dinamik İçerik ve Elementler
**Problem:** Bir listeye yeni bir öğe eklemek ve bu öğenin sayfada göründüğünü doğrulamak.
**Çözüm:** `cy.get()` ile input'a metin girip, `click()` ile butona tıklayarak ve `contains()` ile yeni öğenin varlığını kontrol ederek.
```javascript
// cypress/e2e/todo-list.cy.js
describe('Yapılacaklar Listesi Testleri', () => {
beforeEach(() => {
cy.visit('/todo'); // Uygulamanızın yapılacaklar listesi sayfasını ziyaret edin
});
it('Yeni bir yapılacaklar öğesi ekler', () => {
const newItem = 'Cypress ile test otomasyonunu öğren';
cy.get('.new-todo-input').type(newItem);
cy.get('.add-todo-button').click();
cy.get('.todo-list-item').contains(newItem).should('be.visible');
cy.get('.todo-list-item').should('have.length', 1); // Listede bir öğe olduğunu kontrol et
});
it('Mevcut bir öğeyi tamamlandı olarak işaretler', () => {
cy.get('.new-todo-input').type('Öğeyi tamamla');
cy.get('.add-todo-button').click();
cy.get('.todo-list-item').first().find('input[type="checkbox"]').check();
cy.get('.todo-list-item').first().should('have.class', 'completed');
});
});
```
### Örnek 4: Çapraz Kaynak Politikası (CORS) ve Domainler Arası Test
**Problem:** Farklı bir alan adında (subdomain veya tamamen farklı bir domain) bir kaynağa erişim testi yapmak. Normalde tarayıcılar CORS politikası nedeniyle buna izin vermez.
**Çözüm:** Cypress, `cy.origin()` komutu ile bu tür senaryoları destekler. Bu, özellikle 2026'da mikro-frontend ve çoklu domain mimarilerinin yaygınlaşmasıyla kritik bir özellik haline gelmiştir.
```javascript
// cypress/e2e/cross-origin.cy.js
describe('Çapraz Kaynak Testleri', () => {
it('Farklı bir alt alan adında (subdomain) işlem yapar', () => {
cy.visit('http://localhost:3000'); // Ana uygulamanız
// Örneğin, bir SSO (Single Sign-On) akışında farklı bir kimlik doğrulama domainine yönlendirme
cy.get('#sso-login-button').click(); // Bu tıklama sizi 'auth.example.com'a yönlendirebilir
cy.origin('http://auth.localhost:3000', () => {
cy.get('#username').type('sso_user');
cy.get('#password').type('sso_pass');
cy.get('#login-button').click();
});
cy.url().should('include', '/dashboard'); // Ana domain'e geri dönüldüğünü kontrol et
cy.contains('SSO ile giriş başarılı').should('be.visible');
});
});
```
## İleri Seviye Teknikler: Cypress Mimari Tasarım Kararları
Kurumsal projelerde Cypress'i etkin bir şekilde kullanmak, sadece temel komutları bilmekle kalmaz, aynı zamanda sağlam bir mimari tasarım gerektirir. Ekibimizde Cypress'e geçiş sürecinde öğrendiğimiz 3 kritik ders, iyi bir mimarinin test süitinin sürdürülebilirliğini nasıl artırdığını gösterdi.
### 1. Page Object Model (POM) ve Uygulama
POM, UI test otomasyonunda yaygın olarak kullanılan bir tasarım desenidir. Her sayfa veya önemli UI bileşeni için ayrı bir JavaScript/TypeScript sınıfı veya modülü oluşturarak, element selektörlerini ve sayfa etkileşimlerini merkezi bir yerde toplarız. Bu, testlerin daha okunabilir, bakımı daha kolay ve daha sürdürülebilir olmasını sağlar.
**Neden Önemli:** Bir UI elementi değiştiğinde, sadece ilgili Page Object dosyasını güncellemeniz yeterlidir, bu da yüzlerce testi tek tek değiştirmek zorunda kalmanızın önüne geçer.
```javascript
// cypress/support/page-objects/LoginPage.js
class LoginPage {
getUsernameInput() {
return cy.get('input[name="username"]');
}
getPasswordInput() {
return cy.get('input[name="password"]');
}
getSubmitButton() {
return cy.get('button[type="submit"]');
}
login(username, password) {
this.getUsernameInput().type(username);
this.getPasswordInput().type(password);
this.getSubmitButton().click();
}
}
export default new LoginPage();
```
```javascript
// cypress/e2e/login-pom.cy.js
import LoginPage from '../support/page-objects/LoginPage';
describe('Login Testleri (POM ile)', () => {
beforeEach(() => {
cy.visit('/login');
});
it('POM kullanarak geçerli kimlik bilgileriyle giriş yapar', () => {
LoginPage.login('testuser', 'password123');
cy.url().should('include', '/dashboard');
cy.contains('Hoş Geldiniz, testuser!').should('be.visible');
});
});
```
### 2. Özel Komutlar (Custom Commands) Oluşturma
Tekrar eden test adımlarını veya karmaşık etkileşimleri basitleştirmek için Cypress'in `Cypress.Commands.add()` özelliğini kullanabilirsiniz. Bu, test kodunuzu daha DRY (Don't Repeat Yourself) hale getirir ve okunabilirliği artırır.
**Neden Önemli:** Örneğin, her testin başında bir kullanıcının giriş yapması gerekiyorsa, bunun için tek bir `cy.login()` komutu tanımlayabilirsiniz.
```javascript
// cypress/support/commands.js
Cypress.Commands.add('login', (username, password) => {
cy.visit('/login');
cy.get('input[name="username"]').type(username);
cy.get('input[name="password"]').type(password);
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard');
});
Cypress.Commands.add('addToCart', (productName, quantity = 1) => {
cy.contains(productName).parents('.product-card').find('.add-to-cart-button').click();
cy.get('.cart-item-count').should('contain', quantity);
});
```
```javascript
// cypress/e2e/ecommerce.cy.js
describe('E-ticaret Akışı', () => {
beforeEach(() => {
cy.login('customer', 'securepass'); // Özel komutu kullan
});
it('Ürün sepete ekler ve sepeti kontrol eder', () => {
cy.visit('/products');
cy.addToCart('Laptop Pro X'); // Özel komutu kullan
cy.get('.cart-total').should('contain', '$1200.00');
});
});
```
### 3. Test Verisi Yönetimi
Test verileri, testlerin kararlılığı ve tekrarlanabilirliği için hayati öneme sahiptir. Statik test verileri, fixture'lar, API aracılığıyla dinamik veri oluşturma veya veritabanı temizleme gibi stratejiler kullanılabilir.
**Neden Önemli:** Testlerinizin her zaman aynı başlangıç durumunda çalışmasını sağlamak, hataların tespitini kolaylaştırır ve flaky testleri azaltır. Son projemde, test verilerini API aracılığıyla her testten önce sıfırlamak, test ortamı bağımlılıklarını ortadan kaldırdı.
```javascript
// cypress/fixtures/users.json
[
{
"id": 1,
"username": "testuser",
"password": "password123",
"email": "test@example.com"
},
{
"id": 2,
"username": "admin",
"password": "adminpass",
"email": "admin@example.com"
}
]
```
```javascript
// cypress/e2e/data-management.cy.js
describe('Test Verisi Yönetimi', () => {
it('Fixture dosyasından kullanıcı bilgileriyle giriş yapar', () => {
cy.fixture('users').then((users) => {
const testUser = users[0];
cy.visit('/login');
cy.get('input[name="username"]').type(testUser.username);
cy.get('input[name="password"]').type(testUser.password);
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard');
});
});
it('API kullanarak yeni bir kullanıcı oluşturur ve giriş yapar', () => {
const newUser = {
username: 'dynamicUser',
password: 'dynamicPass',
email: 'dynamic@example.com'
};
cy.request('POST', '/api/register', newUser)
.then((response) => {
expect(response.status).to.eq(201);
cy.login(newUser.username, newUser.password); // Özel komut
});
});
});
```
## Best Practices & Anti-Patterns (2026)
Cypress test süitlerinizin 2026'da da sürdürülebilir, verimli ve güvenilir kalması için uygulamanız gereken en iyi pratikler ve kaçınmanız gereken anti-pattern'lar:
* ✅ **Selektörleri Akıllıca Kullanın:** `data-cy`, `data-test` veya `data-testid` gibi özel `data-*` nitelikleri kullanın. Bu, UI değişikliklerinden daha az etkilenmenizi sağlar.
* **Neden:** `class` veya `id` gibi nitelikler sıkça değişebilirken, test amaçlı eklenen `data-*` nitelikleri daha kararlıdır. Örneğin, ``.
* ❌ **CSS Sınıflarına veya XPath'e Aşırı Bağımlılık:** `cy.get('.my-button-primary')` veya `cy.xpath('//div[contains(@class, "item")]')` gibi selektörler, UI değişikliklerine karşı kırılgandır.
* **Neden:** Geliştiriciler, stil değişiklikleri yaparken bu sınıfları kolayca değiştirebilir, bu da testlerinizin aniden bozulmasına yol açar.
* ✅ **Testleri İzole Tutun:** Her test, birbirinden bağımsız ve tekrarlanabilir olmalıdır. `beforeEach` ve `afterEach` hook'larını kullanarak testler arasında temiz bir durum sağlayın.
* **Neden:** Bir testin diğerini etkilemesini önler, bu da testlerin daha güvenilir olmasını ve hataların daha kolay tespit edilmesini sağlar.
* ❌ **`cy.wait(5000)` Kullanmaktan Kaçının:** Sabit bekleme süreleri, testlerinizi yavaşlatır ve flaky olmasına neden olur. Cypress'in otomatik bekleme mekanizmalarına güvenin.
* **Neden:** Uygulamanızın yanıt süresi değiştiğinde, bu bekleme ya yetersiz kalır (test başarısız olur) ya da gereksiz yere uzar (test yavaşlar).
* ✅ **API İsteklerini Mocklayın veya Stublayın:** Harici bağımlılıkları (API'ler, veritabanları) `cy.intercept()` ile kontrol edin.
* **Neden:** Bu, testlerinizi daha hızlı, daha güvenilir hale getirir ve harici sistemlerin durumundan bağımsız kılar. Gerçek API'lerin yavaşlığı veya kararsızlığı testlerinizi etkilemez.
* ❌ **UI Üzerinden Karmaşık Veri Hazırlığı:** Test verilerini UI üzerinden oluşturmak yerine, `cy.request()` ile doğrudan API çağrıları yaparak hazırlayın.
* **Neden:** UI etkileşimleri yavaştır ve kırılgandır. API üzerinden veri hazırlığı çok daha hızlı ve kararlıdır.
* ✅ **Custom Commands ve Page Object Model Kullanın:** Tekrar eden kodları soyutlayın ve testlerinizi daha okunabilir hale getirin.
* **Neden:** Test süitinizin bakımı kolaylaşır, kod tekrarını azaltır ve yeni test yazmayı hızlandırır.
* ❌ **Testleri Çok Büyük Yazmayın:** Her test senaryosu, tek bir amaca hizmet etmeli ve mümkün olduğunca kısa olmalıdır.
* **Neden:** Büyük testler hata ayıklamayı zorlaştırır ve hangi adımın başarısız olduğunu anlamayı güçleştirir. Bir testin yalnızca bir 'it' bloğu içermesi idealdir.
* ✅ **CI/CD Entegrasyonu:** Cypress testlerini sürekli entegrasyon/sürekli dağıtım (CI/CD) pipeline'ınıza dahil edin.
* **Neden:** Her kod değişikliğinde testlerin otomatik olarak çalıştırılması, hataların erken tespit edilmesini sağlar ve üretim ortamına hatalı kod gitmesini engeller.
* ✅ **Güvenlik Testleri için Özel Senaryolar:** XSS, CSRF gibi temel güvenlik açıklarını simüle eden test senaryoları ekleyin.
* **Neden:** Uygulamanızın temel güvenlik açıklarına karşı dayanıklılığını doğrular. Örneğin, bir metin alanına `` yazarak uygulamanın bunu doğru şekilde işleyip işlemeyeceğini kontrol edebilirsiniz.
## Yaygın Hatalar ve Çözümleri (Troubleshooting)
Cypress ile çalışırken karşılaşılan bazı yaygın sorunlar ve bunların çözümleri, özellikle Stack Overflow'da sıkça sorulan sorulara dayanmaktadır.
1. **Problem: `cy.get(...)` elementi bulamıyor (Element Not Found).**
* **Sebep:** Element henüz DOM'a yüklenmemiş olabilir, yanlış selektör kullanılıyor olabilir veya element görünür olmayabilir.
* **Çözüm:** Selektörünüzü iki kez kontrol edin. Elementin yüklenmesi için Cypress'in otomatik bekleme mekanizmasına güvenin; eğer bu yeterli değilse, `cy.should('be.visible')` veya `cy.should('exist')` gibi assertion'lar ekleyerek elementin varlığını teyit edin. Dinamik içeriklerde `cy.contains()` kullanmak daha sağlam olabilir. Eğer bir `iframe` içinde çalışıyorsanız, Cypress'in `iframe` desteğini kullanmanız gerekir.
2. **Problem: Testler lokalde çalışıyor ama CI/CD'de başarısız oluyor.**
* **Sebep:** CI/CD ortamında farklı bir Node.js versiyonu, farklı tarayıcı versiyonu, eksik bağımlılıklar veya headless modda çalışma sorunları olabilir. Bazen CI ortamı daha yavaş olduğu için zaman aşımı (timeout) sorunları yaşanabilir.
* **Çözüm:** CI/CD pipeline'ınızdaki Node.js ve tarayıcı versiyonlarının lokalinizle aynı olduğundan emin olun. `cypress run --headless` komutunu kullanarak lokalde de headless modda test edin. Cypress yapılandırmasında `defaultCommandTimeout` değerini artırmayı düşünebilirsiniz (ancak bu, bir `cy.wait()` anti-pattern'ı değildir, genel bir zaman aşımı ayarıdır). Ayrıca, CI ortamında yeterli kaynak (CPU, RAM) olduğundan emin olun.
3. **Problem: Tarayıcılar arası (Cross-Origin) istekler başarısız oluyor.**
* **Sebep:** Tarayıcı güvenlik politikaları (CORS) nedeniyle farklı bir domain'den yapılan istekler engellenir.
* **Çözüm:** Cypress 14.x ve üzeri sürümlerde `cy.origin()` komutunu kullanarak farklı domain'lerdeki işlemleri test edebilirsiniz. Alternatif olarak, `cypress.config.js` dosyasında `chromeWebSecurity: false` ayarını geçici olarak devre dışı bırakabilirsiniz (ancak bu, güvenlik riskleri taşıdığı için dikkatli kullanılmalıdır ve sadece test ortamında önerilir). En iyi pratik, API isteklerini `cy.intercept()` ile mocklamak veya backend'i CORS'u test ortamında izin verecek şekilde yapılandırmaktır.
4. **Problem: `cy.click()` bir elementi tıklayamıyor.**
* **Sebep:** Element başka bir elementin altında kalmış olabilir, görünmez olabilir veya tıklanabilir durumda olmayabilir (örneğin, devre dışı bırakılmış bir buton).
* **Çözüm:** `cy.get('selector').click({ force: true })` kullanarak zorla tıklama yapmayı deneyin (ancak bu, gerçek kullanıcı davranışını yansıtmadığı için genellikle bir anti-pattern'dır). Elementin gerçekten görünür ve etkileşime açık olduğundan emin olmak için `cy.get('selector').should('be.visible').click()` kullanın. Eğer element animasyonluysa, animasyonun bitmesini beklemek için `cy.wait()` yerine `cy.get('selector').should('not.have.class', 'is-animating').click()` gibi daha akıllıca beklemeler kullanın.
## Performans Optimizasyonu
Büyük test süitlerinde performans, test geri bildirim döngüsünün hızını doğrudan etkiler. 2026'da bile, testlerin dakikalarca sürmesi geliştirici verimliliğini düşürebilir. Son projemde, Cypress testlerinin çalışma süresini %40 oranında azaltarak, geliştiricilerin CI/CD pipeline'ından daha hızlı geri bildirim almasını sağladık. İşte Cypress testlerinizi optimize etmek için kullanabileceğiniz teknikler:
1. **Paralel Test Çalıştırma:** Cypress Cloud (eski adıyla Dashboard) veya açık kaynaklı alternatifler (örneğin `Sorry-Cypress`) kullanarak testlerinizi birden fazla makinede veya konteynerde paralel olarak çalıştırın. Bu, test süitenizin toplam çalışma süresini önemli ölçüde azaltır.
* **Metrik:** 100 testin tek makinede 10 dakika sürmesi yerine, 4 paralel işçi ile 2.5 dakikaya düşebilir.
2. **Test Bölme (Test Sharding):** Test süitinizi eşit parçalara bölerek paralel işçilere dağıtın. Cypress Cloud, test geçmişine göre en uygun bölmeyi otomatik olarak yapabilir.
3. **Gereksiz `cy.wait()` Kullanımından Kaçının:** Daha önce de belirtildiği gibi, sabit `cy.wait()` komutları testleri yavaşlatır. Cypress'in otomatik bekleme mekanizmalarına güvenin veya `cy.intercept()` ile ağ isteklerini kontrol ederek daha akıllıca beklemeler yapın.
4. **`cy.request()` Kullanımı:** Veri hazırlığı veya temizliği gibi UI gerektirmeyen işlemleri `cy.request()` ile doğrudan API üzerinden yapın. Bu, UI etkileşimlerinden çok daha hızlıdır.
* **Before/After:** UI üzerinden 5 adımda kullanıcı oluşturmak 5 saniye sürerken, `cy.request()` ile 500 ms'de tamamlanabilir.
5. **Headless Modda Çalıştırma:** CI/CD ortamlarında testleri her zaman headless modda çalıştırın (`cypress run --headless`). Bu, tarayıcı UI'sının render edilmesiyle ilgili performansı artırır.
6. **Video Kaydını Devre Dışı Bırakma:** Her test çalıştırmasında video kaydı yapmak, CI/CD ortamlarında disk alanı ve CPU tüketimini artırabilir. Sadece başarısız testler için video kaydını etkinleştirmeyi düşünebilirsiniz (`cypress.config.js` içinde `video: false` veya `videoUploadOnPasses: false`).
7. **Sadece Etkilenen Testleri Çalıştırma:** Kod değişikliklerinin sadece ilgili testleri tetiklemesini sağlayan akıllı test çalıştırma stratejileri geliştirin. `cypress-split` gibi araçlar bu konuda yardımcı olabilir.
8. **Tarayıcı Kaynaklarını İzleme:** Testlerinizin tarayıcıda ne kadar bellek ve CPU kullandığını izleyin. Aşırı kaynak tüketimi, testlerin yavaşlamasına veya kararsız hale gelmesine neden olabilir. Tarayıcının geliştirici araçları veya Cypress'in kendi performans izleme araçları kullanılabilir.
## Gerçek Dünya Proje Örneği: Mikro-Frontend ile Cypress Test Mimarisi (2026)
Bu bölümde, modern bir mikro-frontend mimarisinde Cypress'in nasıl entegre edildiğini gösteren basit bir örnek proje sunacağız. Amacımız, farklı mikro-frontend'lerin bir arada çalıştığı bir ana uygulama için uçtan uca testlerin nasıl yapılandırılabileceğini göstermektir.
**Senaryo:** Bir ana uygulama (`shell-app`) ve iki mikro-frontend (`auth-app`, `product-app`) olduğunu varsayalım. `auth-app` kullanıcı girişi sağlarken, `product-app` ürün listesini gösterir. `shell-app` ise bu ikisini birleştirir.
**Dosya Yapısı:**
```
my-micro-frontend-project/
├── cypress/
│ ├── e2e/
│ │ ├── auth.cy.js
│ │ └── product.cy.js
│ ├── support/
│ │ ├── commands.js
│ │ └── e2e.js
│ └── cypress.config.js
├── shell-app/
├── auth-app/
└── product-app/
```
**`cypress.config.js` (Önemli Yapılandırmalar):**
```javascript
// cypress.config.js (2026 Güncel)
import { defineConfig } from 'cypress';
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000', // Ana uygulamanın çalıştığı adres
setupNodeEvents(on, config) {
// Node.js olaylarını burada dinleyebilirsiniz (örneğin, veritabanı temizliği)
},
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
supportFile: 'cypress/support/e2e.js',
chromeWebSecurity: false, // Mikro-frontend'ler arası geçişler için gerekebilir
viewportWidth: 1280,
viewportHeight: 720,
video: false, // CI/CD'de performansı artırmak için kapatılabilir
screenshotOnRunF