Anda sudah menjalankan Cypress untuk pengujian end-to-end. Sekarang Anda ingin langsung mengakses API, memeriksa kode status, dan menegaskan body JSON tanpa mengklik melalui UI. Cypress dapat melakukannya. Perintah cy.request() mengirimkan permintaan HTTP nyata dari Node, di luar browser, sehingga Anda dapat menguji endpoint secara mandiri atau mengatur status sebelum pengujian UI berjalan.
Panduan ini menunjukkan cara menguji API dengan Cypress: dasar-dasar cy.request(), menegaskan respons, menggabungkan permintaan untuk menggunakan kembali token autentikasi, dan mem-stub lalu lintas browser dengan cy.intercept(). Anda juga akan melihat kapan Cypress-untuk-API cocok dan kapan alat asli-API lebih sesuai.
Mengapa menguji API dengan Cypress
Sebagian besar suite Cypress menjalankan browser. Namun banyak dari yang Anda verifikasi di UI adalah API di bawahnya: apakah /login mengembalikan token, apakah /users mengembalikan bentuk yang benar, apakah POST membuat catatan yang Anda harapkan.
Menguji endpoint-endpoint tersebut secara langsung memiliki dua keuntungan. Pertama, pemeriksaan API berjalan lebih cepat daripada alur UI karena tidak ada rendering, tidak ada menunggu elemen. Kedua, Anda dapat menggunakan cy.request() untuk menyiapkan data pengujian. Alih-alih mengklik formulir pendaftaran untuk membuat pengguna, Anda mengirim satu POST dan beralih ke penegasan yang benar-benar Anda pedulikan.
Jika Cypress sudah ada di tumpukan teknologi Anda, menambahkan pengujian API berarti tidak perlu menginstal alat baru. Anda menuliskannya di file spesifikasi yang sama, dengan penegasan expect yang sama, dalam jalankan CI yang sama.
Dasar-dasar cy.request()
cy.request() membuat permintaan HTTP dan menghasilkan respons. Ini berjalan dari proses Node Cypress, bukan browser, sehingga tidak tunduk pada aturan CORS atau same-origin.
Perintah ini menerima beberapa bentuk:
cy.request(url)
cy.request(url, body)
cy.request(method, url)
cy.request(method, url, body)
cy.request(options)
Panggilan paling sederhana meneruskan URL. Tanpa metode, Cypress secara default akan menggunakan GET:
cy.request('https://jsonplaceholder.typicode.com/users')
Untuk apa pun di luar GET dasar, teruskan objek opsi. Ini memberi Anda kendali penuh atas metode, body, dan header:
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
}
})
Opsi yang berguna pada objek tersebut:
method: kata kerja HTTP (GET,POST,PUT,PATCH,DELETE, dan lainnya). Default keGET.url: endpoint. Wajib.body: payload permintaan. Cypress meng-serialisasi objek ke JSON.headers: objek header permintaan.auth: kredensial untuk Otentikasi Dasar HTTP.qs: parameter string kueri sebagai objek.failOnStatusCode: atur kefalseketika Anda ingin menegaskan pada respons 4xx atau 5xx alih-alih membuat pengujian gagal.
Opsi terakhir itu penting untuk pengujian negatif. Secara default cy.request() akan menggagalkan pengujian pada status non-2xx atau non-3xx apa pun. Jika Anda memeriksa bahwa permintaan yang buruk mengembalikan 400, Anda harus memilih keluar:
cy.request({
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/users/99999',
failOnStatusCode: false
}).then((response) => {
expect(response.status).to.eq(404)
})
Menegaskan status dan body
cy.request() menghasilkan objek respons. Rantaikan .then() untuk membacanya. Respons tersebut memiliki empat properti yang paling sering Anda gunakan:
status: kode status HTTP.body: payload respons. Cypress mengurai objek ini menjadi objek JavaScript ketikaContent-Typeberakhiranjson.headers: header respons.duration: berapa lama permintaan berlangsung, dalam milidetik.
Berikut adalah pengujian lengkap yang memeriksa status, bentuk body, dan bidang tertentu:
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')
})
})
})
Karena response.body sudah merupakan objek yang diurai, Anda dapat menegaskannya dengan Chai standar. Anda dapat memeriksa tipe, panjang, properti bersarang, atau nilai yang tepat. Ini adalah sintaks penegasan yang sama yang Anda gunakan untuk pengujian UI, jadi tidak ada hal baru untuk dipelajari.
Anda juga dapat menegaskan header respons, yang berguna untuk memeriksa tipe konten atau caching:
cy.request('https://jsonplaceholder.typicode.com/users').then((response) => {
expect(response.headers['content-type']).to.include('application/json')
})
Untuk melihat lebih dalam tentang struktur pemeriksaan ini, lihat panduan kami tentang penegasan API dan praktik terbaik pengujian API yang lebih luas.
Menggabungkan permintaan dan menggunakan kembali token autentikasi
API nyata membutuhkan autentikasi. Pola umum adalah masuk sekali, mengambil token, lalu mengirimkannya pada setiap permintaan berikutnya. cy.request() dapat digabungkan dengan rapi untuk ini.
Kirim permintaan masuk, baca token dari body respons, lalu gunakan dalam panggilan berikutnya:
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')
})
})
})
})
Jika beberapa pengujian membutuhkan token yang sama, pindahkan login ke beforeEach dan simpan token dengan Cypress.env() atau alias yang dibungkus agar setiap pengujian dapat mengambilnya. Ini menjaga pengaturan autentikasi di satu tempat alih-alih mengulanginya di setiap spesifikasi.
Pola login-lalu-gunakan ini adalah bentuk yang sama yang akan Anda tulis dalam alur pengujian integrasi API mana pun, di mana satu panggilan memasukkan data ke panggilan berikutnya.
cy.intercept() untuk stubbing
cy.request() memanggil API nyata. Terkadang Anda menginginkan yang sebaliknya: mencegat permintaan yang dibuat aplikasi front-end Anda dan mengembalikan respons palsu. Itulah cy.intercept().
Ada perbedaan penting di sini. cy.intercept() hanya mencegat permintaan yang dibuat oleh aplikasi front-end Anda di browser. Ini tidak mencegat cy.request(), karena cy.request() sepenuhnya melewati browser. Gunakan cy.intercept() saat Anda menguji bagaimana UI Anda bereaksi terhadap respons API tertentu, bukan saat Anda menguji API itu sendiri.
Anda dapat memata-matai permintaan, men-stub-nya dengan respons statis, atau menunggunya. Untuk men-stub, teruskan objek respons:
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [{ id: 1, name: 'Ada' }]
})
Sekarang setiap permintaan browser ke /api/users mengembalikan payload tetap itu. Ini memungkinkan Anda menguji kasus-kasus ekstrem yang sulit dipicu terhadap backend langsung, seperti daftar kosong, kesalahan 500, atau respons yang lambat.
Untuk menegaskan bahwa permintaan terjadi, buat alias dengan .as() dan tunggu:
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')
})
Baris cy.wait('@getUsers') menghentikan pengujian hingga permintaan yang dicegat selesai, lalu memberikan Anda permintaan dan respons untuk ditegaskan. Siapkan intercept sebelum tindakan yang memicu permintaan, atau tidak akan menangkap apa pun. Jika Anda mempertimbangkan kapan harus memalsukan respons versus memalsukan seluruh layanan, postingan kami tentang API mocking dan API stubbing vs API mocking menguraikan komprominya.
Kapan Cypress-untuk-API masuk akal, dan kapan tidak
Cypress sangat cocok untuk pemeriksaan API yang berada dalam suite pengujian UI. Jika Anda sudah menulis pengujian e2e dan perlu mengisi data, memverifikasi endpoint yang bergantung pada UI Anda, atau memalsukan respons untuk menguji penanganan kesalahan, cy.request() dan cy.intercept() menjaga semuanya di satu tempat. Tidak ada perpindahan konteks, tidak ada alat kedua.
Ini juga baik untuk beberapa pengujian asap API mandiri ketika Cypress adalah satu-satunya pelari pengujian Anda dan Anda tidak ingin menambahkan dependensi lain.
Yang menjadi canggung adalah suite pengujian API mandiri yang besar. Cypress dibangun untuk browser, sehingga pengujian API adalah kemampuan yang ditambahkan di atasnya, bukan desain inti. Beberapa celah muncul seiring pertumbuhan suite:
- Tidak ada pembuat permintaan visual. Setiap permintaan adalah kode. Membuat header, body, dan parameter kueri secara manual menjadi lambat ketika Anda memiliki ratusan endpoint.
- Lebih lemah untuk pipeline API khusus CI. Cypress memutar konteks browser bahkan untuk menjalankan API murni, yang merupakan overhead yang tidak Anda perlukan.
- Tidak ada definisi API yang dibagikan. Bentuk permintaan ada di file pengujian Anda, bukan dalam spesifikasi yang dapat digunakan kembali oleh tim Anda di seluruh desain, dokumen, dan pengujian.
Di sinilah alat asli-API lebih cocok. Apidog dibangun di sekitar API itu sendiri: Anda mendesain endpoint sekali, lalu membangun skenario pengujian terhadapnya dengan pembuat permintaan visual dan penegasan visual, tanpa kode yang diperlukan untuk kasus-kasus umum. Permintaan, lingkungan, dan autentikasi hidup di ruang kerja bersama, sehingga tim Anda tidak perlu memperolehnya kembali dari file pengujian.
Untuk CI, Apidog CLI menjalankan skenario pengujian yang Anda simpan secara tanpa kepala di setiap langkah yang dapat menjalankan Node:
npm install -g apidog-cli
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
Flag -t menargetkan skenario atau suite yang disimpan, -e memilih lingkungan, dan -r memilih format laporan (cli, html, json, junit). Output JUnit langsung terhubung ke sebagian besar dasbor CI. Tambahkan -d atau --iteration-data untuk menjalankan pengujian dari file data, dan --upload-report untuk mendorong hasil kembali ke ruang kerja Anda. CLI menjalankan skenario yang disimpan; ini bukan pengirim permintaan interaktif.
Cara yang berguna untuk memikirkannya: gunakan cy.request() untuk pemeriksaan API yang mendukung pengujian browser Anda, dan gunakan alat asli-API ketika pengujian API adalah tugas utama. Jika Anda membandingkan pilihan, rangkuman kami tentang alat otomatisasi pengujian API yang berjalan di CI/CD dan 30 alat pengujian API terbaik yang lebih luas mencakup bidang ini.
FAQ
Apakah cy.request() berjalan di browser?
Tidak. cy.request() berjalan dari proses Node Cypress, di luar browser. Itulah mengapa tidak diblokir oleh CORS atau kebijakan same-origin, dan mengapa cy.intercept() tidak dapat mencegatnya. Jika Anda memerlukan permintaan yang dibuat browser, picu melalui aplikasi Anda dan tangkap dengan cy.intercept().
Bagaimana cara menguji respons 400 atau 404 tanpa menggagalkan pengujian?
Secara default cy.request() gagal pada status non-2xx atau non-3xx apa pun. Atur failOnStatusCode: false dalam objek opsi, lalu tegaskan statusnya sendiri dengan expect(response.status).to.eq(404).
Dapatkah saya menggunakan cy.request() untuk masuk sebelum pengujian UI?
Ya, dan ini adalah pola umum. Kirim POST ke endpoint login Anda dengan cy.request(), baca token dari response.body, dan simpan (di Cypress.env(), localStorage, atau cookie) sehingga pengujian UI Anda dimulai dalam keadaan terautentikasi. Ini melewati formulir login dan mempercepat suite.
Apa perbedaan antara cy.request() dan cy.intercept()?
cy.request() mengirimkan permintaan HTTP nyata dan mengembalikan respons aktual, jadi Anda menggunakannya untuk menguji API. cy.intercept() memantau atau memalsukan permintaan yang dibuat oleh front-end Anda di browser, jadi Anda menggunakannya untuk mengontrol apa yang diterima UI Anda. Yang satu memukul jaringan; yang lain membentuknya.
Haruskah saya menggunakan Cypress atau alat khusus untuk pengujian API?
Gunakan Cypress ketika pemeriksaan API mendukung suite pengujian browser yang sudah Anda jalankan. Untuk suite API mandiri yang besar, pipeline API khusus CI, atau definisi API bersama yang digunakan seluruh tim Anda, alat asli-API seperti Apidog lebih cocok. Lihat praktik terbaik pengujian API kami untuk memutuskan.
