Uçtan uca testlerinizde Cypress kullanıyorsanız, aynı test koşucusuyla API uç noktalarını da doğrudan doğrulayabilirsiniz. cy.request() komutu tarayıcı dışında, Cypress’in Node sürecinden gerçek HTTP istekleri gönderir. Böylece bir endpoint’in durum kodunu, JSON gövdesini ve başlıklarını UI üzerinden tıklama yapmadan test edebilir veya UI testinden önce gerekli veriyi hazırlayabilirsiniz.
Bu rehberde Cypress ile API testi için pratik akışı göreceksiniz: cy.request() kullanımı, yanıt doğrulama, kimlik doğrulama token’ını sonraki isteklere taşıma ve cy.intercept() ile tarayıcı trafiğini stub etme. Ayrıca Cypress’in API testi için ne zaman yeterli olduğunu, ne zaman API odaklı bir aracın daha uygun olacağını ele alacağız.
Neden API'leri Cypress ile test etmelisiniz?
Cypress genellikle tarayıcı tabanlı uçtan uca testler için kullanılır. Ancak UI’da doğruladığınız pek çok davranış, arka plandaki API’ye bağlıdır:
-
/logindoğru token’ı döndürüyor mu? -
/usersbeklenen veri yapısını sağlıyor mu? - Bir
POSTisteği beklenen kaydı oluşturuyor mu? - Hatalı isteklerde doğru durum kodları dönüyor mu?
Bu endpoint’leri doğrudan test etmek iki açıdan faydalıdır:
- Daha hızlı geri bildirim alırsınız. Render, selector bekleme ve kullanıcı etkileşimi yoktur.
-
Test verisini daha hızlı hazırlarsınız. Form doldurmak yerine
cy.request()ile doğrudan kayıt oluşturabilirsiniz.
Cypress zaten test yığınınızdaysa, API kontrollerini aynı spec dosyalarında, aynı expect doğrulamalarıyla ve aynı CI çalıştırmasında tutabilirsiniz.
cy.request() temelleri
cy.request() bir HTTP isteği gönderir ve yanıt nesnesini döndürür. İstek tarayıcıdan değil Cypress’in Node sürecinden gittiği için CORS veya same-origin kurallarına takılmaz.
Desteklenen temel kullanım biçimleri:
cy.request(url)
cy.request(url, body)
cy.request(method, url)
cy.request(method, url, body)
cy.request(options)
En basit kullanımda Cypress varsayılan olarak GET isteği gönderir:
cy.request('https://jsonplaceholder.typicode.com/users')
Daha kontrollü bir istek için options nesnesi kullanın:
cy.request({
method: 'POST',
url: 'https://jsonplaceholder.typicode.com/posts',
headers: {
'Content-Type': 'application/json'
},
body: {
title: 'API test',
body: 'created from Cypress',
userId: 1
}
})
Sık kullanılan seçenekler:
| Seçenek | Açıklama |
|---|---|
method |
HTTP metodu: GET, POST, PUT, PATCH, DELETE vb. Varsayılan GET. |
url |
İstek gönderilecek endpoint. |
body |
İstek payload’u. Cypress nesneleri JSON’a dönüştürür. |
headers |
İstek başlıkları. |
auth |
HTTP Basic Auth kimlik bilgileri. |
qs |
Query string parametreleri. |
failOnStatusCode |
false yapılırsa 4xx/5xx yanıtlar testi otomatik başarısız yapmaz. |
Negatif senaryolarda failOnStatusCode: false önemlidir. Varsayılan davranışta Cypress, 2xx veya 3xx olmayan yanıtları test hatası sayar.
cy.request({
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/users/99999',
failOnStatusCode: false
}).then((response) => {
expect(response.status).to.eq(404)
})
Durum kodu, gövde ve başlık doğrulama
cy.request() yanıtı .then() içinde okunur. En çok kullanacağınız alanlar:
-
response.status: HTTP durum kodu -
response.body: Yanıt gövdesi -
response.headers: Yanıt başlıkları -
response.duration: İstek süresi, milisaniye cinsinden
Örnek bir GET testi:
describe('Users API', () => {
it('returns a list of users', () => {
cy.request('https://jsonplaceholder.typicode.com/users').then((response) => {
expect(response.status).to.eq(200)
expect(response.body).to.be.an('array')
expect(response.body).to.have.length(10)
expect(response.body[0]).to.have.property('email')
})
})
})
response.body JSON ise Cypress bunu otomatik olarak JavaScript nesnesine ayrıştırır. Bu yüzden standart Chai assertion’larını kullanabilirsiniz:
expect(response.body).to.be.an('array')
expect(response.body[0]).to.have.property('email')
expect(response.body[0].address).to.have.property('city')
Başlık doğrulama örneği:
cy.request('https://jsonplaceholder.typicode.com/users').then((response) => {
expect(response.headers['content-type']).to.include('application/json')
})
Daha kapsamlı doğrulama stratejileri için API doğrulamaları ve API test en iyi uygulamaları rehberlerine bakabilirsiniz.
İstekleri zincirleme ve token yeniden kullanma
Gerçek API’lerde çoğu endpoint kimlik doğrulama gerektirir. Tipik akış:
- Login endpoint’ine istek gönder.
- Yanıttan token’ı al.
- Token’ı sonraki isteklerde
Authorizationbaşlığında kullan.
describe('Authenticated API flow', () => {
it('logs in and fetches a protected resource', () => {
cy.request({
method: 'POST',
url: 'https://api.example.com/login',
body: {
email: 'user@example.com',
password: 'secret'
}
}).then((loginResponse) => {
expect(loginResponse.status).to.eq(200)
const token = loginResponse.body.token
cy.request({
method: 'GET',
url: 'https://api.example.com/profile',
headers: {
Authorization: `Bearer ${token}`
}
}).then((profileResponse) => {
expect(profileResponse.status).to.eq(200)
expect(profileResponse.body).to.have.property('email', 'user@example.com')
})
})
})
})
Birden fazla test aynı token’a ihtiyaç duyuyorsa login işlemini beforeEach içine taşıyabilirsiniz:
describe('Protected API', () => {
beforeEach(() => {
cy.request({
method: 'POST',
url: 'https://api.example.com/login',
body: {
email: 'user@example.com',
password: 'secret'
}
}).then((response) => {
Cypress.env('authToken', response.body.token)
})
})
it('fetches profile', () => {
cy.request({
method: 'GET',
url: 'https://api.example.com/profile',
headers: {
Authorization: `Bearer ${Cypress.env('authToken')}`
}
}).then((response) => {
expect(response.status).to.eq(200)
})
})
})
Bu yaklaşım, bir isteğin çıktısının sonraki isteğe girdi olduğu API entegrasyon testi akışlarında da kullanılır.
UI testinden önce veri hazırlama
cy.request() yalnızca API’yi test etmek için değil, UI testlerini hızlandırmak için de kullanışlıdır.
Örneğin bir kullanıcıyı arayüzden oluşturmak yerine testten önce API ile oluşturabilirsiniz:
beforeEach(() => {
cy.request({
method: 'POST',
url: 'https://api.example.com/users',
body: {
name: 'Test User',
email: `test-${Date.now()}@example.com`
}
}).then((response) => {
expect(response.status).to.eq(201)
Cypress.env('userId', response.body.id)
})
})
Sonra UI testinde yalnızca doğrulamak istediğiniz davranışa odaklanırsınız:
it('shows user detail page', () => {
cy.visit(`/users/${Cypress.env('userId')}`)
cy.contains('Test User').should('be.visible')
})
Bu yöntem, testleri daha hızlı ve daha az kırılgan hale getirir.
Stub için cy.intercept() kullanımı
cy.request() gerçek API’ye istek gönderir. Bazen ise tam tersine ihtiyacınız olur: Ön uç uygulamanızın tarayıcıdan yaptığı isteği yakalayıp sahte bir yanıt döndürmek.
Bunun için cy.intercept() kullanılır.
Önemli fark:
-
cy.request()Cypress Node sürecinden gerçek HTTP isteği gönderir. -
cy.intercept()yalnızca tarayıcıdan çıkan uygulama isteklerini yakalar. -
cy.intercept()bircy.request()çağrısını yakalamaz.
Basit stub örneği:
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [{ id: 1, name: 'Ada' }]
})
Bu tanımdan sonra uygulama /api/users isteği yaptığında gerçek backend yerine bu sabit yanıtı alır.
Hata senaryosu testi:
it('shows an error banner when the API fails', () => {
cy.intercept('GET', '/api/users', {
statusCode: 500,
body: { message: 'Server error' }
}).as('getUsers')
cy.visit('/dashboard')
cy.wait('@getUsers')
.its('response.statusCode')
.should('eq', 500)
cy.contains('Something went wrong').should('be.visible')
})
cy.intercept() her zaman isteği tetikleyen aksiyondan önce kurulmalıdır. Aksi halde Cypress isteği yakalayamaz.
Stub ve mock stratejileri için API mocking ve API stubbing vs API mocking yazılarına bakabilirsiniz.
Cypress API testi için ne zaman uygundur?
Cypress şu durumlarda iyi bir seçimdir:
- Zaten Cypress ile UI/E2E testleri yazıyorsanız
- UI testinden önce test verisi hazırlamak istiyorsanız
- Uygulamanızın bağlı olduğu birkaç kritik API endpoint’ini smoke test etmek istiyorsanız
- UI’nın belirli API yanıtlarına nasıl tepki verdiğini
cy.intercept()ile test etmek istiyorsanız - Ek bir araç eklemeden temel API kontrollerini aynı CI akışında çalıştırmak istiyorsanız
Örnek kullanım:
it('creates a record through API and verifies it in UI', () => {
cy.request({
method: 'POST',
url: 'https://api.example.com/items',
body: {
name: 'Created from Cypress'
}
}).then((response) => {
expect(response.status).to.eq(201)
cy.visit(`/items/${response.body.id}`)
cy.contains('Created from Cypress').should('be.visible')
})
})
Cypress API testi için ne zaman sınırlı kalır?
Büyük ve bağımsız bir API test paketi oluşturuyorsanız Cypress her zaman en uygun araç olmayabilir. Çünkü Cypress’in temel tasarımı tarayıcı testleri içindir; API testi sonradan eklenen bir yetenektir.
Büyüyen API test paketlerinde şu sınırlamalar ortaya çıkabilir:
- Görsel istek oluşturucu yoktur; tüm istekler kodla yazılır.
- Çok sayıda endpoint için header, body ve query parametrelerini elle yönetmek zorlaşır.
- Sadece API testleri için CI’da Cypress çalıştırmak gereksiz tarayıcı yükü oluşturabilir.
- API tasarımı, dokümantasyon ve testler arasında paylaşılan tek bir tanım bulunmaz.
- Ekip içi ortak ortam, auth ve senaryo yönetimi için ek yapılandırma gerekir.
Bu noktada API odaklı bir araç daha uygun olabilir. Apidog, API tasarımı, istek oluşturma, test senaryoları, ortamlar ve kimlik doğrulamayı ortak bir çalışma alanında yönetmek için kullanılabilir. Endpoint’i bir kez tanımlayıp aynı tanımı test, dokümantasyon ve senaryo çalıştırma süreçlerinde yeniden kullanabilirsiniz.
CI tarafında Apidog CLI ile kaydedilmiş test senaryolarını headless çalıştırabilirsiniz:
npm install -g apidog-cli
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
Parametreler:
-
-t: Çalıştırılacak senaryo veya suite ID’si -
-e: Kullanılacak environment ID’si -
-r: Rapor formatları:cli,html,json,junit -
-dveya--iteration-data: Veri dosyası ile iterasyonlu test çalıştırma -
--upload-report: Sonuçları çalışma alanına geri gönderme
Özet karar kuralı:
- UI testlerinizi destekleyen API kontrolleri için
cy.request()kullanın. - API testi ana işiniz haline geldiyse API odaklı bir araç kullanın.
Alternatifleri karşılaştırmak için CI/CD’de çalışan API test otomasyon araçları ve en iyi 30 API test aracı listelerine göz atabilirsiniz.
Sıkça Sorulan Sorular
cy.request() tarayıcıda mı çalışır?
Hayır. cy.request() tarayıcı dışında, Cypress’in Node sürecinden çalışır. Bu yüzden CORS veya same-origin politikası tarafından engellenmez. Ayrıca cy.intercept() tarafından yakalanmaz.
400 veya 404 yanıtını testi başarısız yapmadan nasıl test ederim?
failOnStatusCode: false kullanın:
cy.request({
method: 'GET',
url: 'https://api.example.com/missing-resource',
failOnStatusCode: false
}).then((response) => {
expect(response.status).to.eq(404)
})
UI testinden önce login olmak için cy.request() kullanabilir miyim?
Evet. Bu yaygın bir yaklaşımdır. Login endpoint’ine POST gönderip token’ı alabilir, sonra token’ı localStorage, cookie veya Cypress.env() içinde saklayabilirsiniz. Böylece login formunu atlayıp testi doğrudan kimliği doğrulanmış durumda başlatırsınız.
cy.request() ile cy.intercept() arasındaki fark nedir?
cy.request() gerçek HTTP isteği gönderir ve gerçek yanıtı döndürür. API endpoint’ini doğrudan test etmek için kullanılır.
cy.intercept() ise tarayıcıdan çıkan uygulama isteklerini izler, bekler veya stub eder. UI’nın belirli API yanıtlarına nasıl tepki verdiğini test etmek için kullanılır.
API testi için Cypress mi yoksa özel bir araç mı kullanmalıyım?
Zaten Cypress ile çalışan bir tarayıcı test paketiniz varsa ve API kontrolleri bu testleri destekliyorsa Cypress yeterlidir. Büyük, bağımsız ve ekip genelinde yönetilen bir API test paketi için Apidog gibi API odaklı bir araç daha uygundur. Daha fazla karar kriteri için API test en iyi uygulamaları yazısına bakabilirsiniz.
Top comments (0)