Sebuah *deploy* dilakukan pada pukul 4 sore di hari Jumat. *Unit tests* berwarna hijau, kontainer berhasil dibuat, peluncuran selesai tanpa kesalahan. Kemudian antrean dukungan mulai terisi: pembayaran menampilkan 500s. *Bug* itu tidak pernah ada di kode yang diuji. Itu ada pada bagaimana dua layanan berkomunikasi satu sama lain, dan tidak ada pengujian dalam *pipeline* yang pernah melatih percakapan itu.
Itulah celah yang seharusnya ditutup oleh otomatisasi pengujian dalam DevOps, dan bagian yang paling sering diabaikan oleh sebagian besar tim adalah lapisan API. *Unit tests* membuktikan bahwa sebuah fungsi bekerja secara terisolasi. *End-to-end UI tests* membuktikan bahwa sebuah peramban dapat mengklik alur, secara lambat dan tidak stabil. Kontrak antara layanan-layanan Anda, hal yang sebenarnya rusak dalam produksi, berada di tengah dan sering tidak diperiksa. Tes API berada persis di sana.
Apa sebenarnya arti otomatisasi pengujian dalam DevOps
DevOps adalah sebuah lingkaran, bukan garis. Rencanakan, kodekan, bangun, uji, rilis, *deploy*, operasikan, pantau, lalu kembali ke rencana. Otomatisasi pengujian dalam DevOps berarti pengujian berjalan secara otomatis pada titik-titik dalam lingkaran tersebut di mana mereka menangkap masalah paling murah, alih-alih menjadi gerbang manual yang dijalankan seseorang sekali sebelum rilis.

Prinsip di baliknya adalah *shift-left*: memindahkan pengujian lebih awal, lebih dekat ke saat pengembang menulis perubahan. Sebuah *bug* yang tertangkap pada *pull request* membutuhkan waktu beberapa menit untuk diperbaiki. *Bug* yang sama yang tertangkap dalam produksi membutuhkan *rollback*, saluran insiden, dan *postmortem*. Otomatisasi adalah yang memungkinkan *shifting left*, karena manusia tidak dapat secara manual menjalankan ulang serangkaian regresi pada setiap *commit*, tetapi sebuah *pipeline* bisa.
Kesalahannya adalah memperlakukan "otomatisasi pengujian" sebagai satu wadah. Piramida pengujian membaginya menjadi beberapa lapisan, dan setiap lapisan menjawab pertanyaan yang berbeda:
- *Unit tests* bertanya apakah sebuah fungsi tunggal mengembalikan nilai yang benar. Mereka cepat dan banyak.
- *API and integration tests* bertanya apakah layanan Anda menghasilkan respons yang benar dan berkomunikasi satu sama lain dengan benar. Lebih sedikit dari ini, tetapi masing-masing mencakup area yang lebih luas.
- *End-to-end tests* bertanya apakah seluruh sistem berfungsi dari sudut pandang pengguna. Lambat, rapuh, dan layak untuk dijaga agar tetap sedikit.
Tes API berada di tengah yang produktif. Mereka berjalan dalam hitungan detik, bukan menit. Mereka tidak bergantung pada UI yang dirender, sehingga mereka tidak rusak ketika sebuah tombol bergerak. Dan mereka menguji permukaan yang sebenarnya bergantung pada layanan lain dan pelanggan Anda. Itulah mengapa, dalam *pipeline* DevOps, tes API mengemban lebih banyak beban penangkapan regresi daripada lapisan lainnya. Untuk dasar-dasar praktiknya sendiri, otomatisasi pengujian API mencakup apa yang harus ditegaskan dan mengapa sebelum Anda khawatir tentang di mana ia berjalan.
Siklus hidup DevOps, tahap demi tahap, dan di mana tes API cocok
Ini adalah peta praktisnya. Tidak setiap tim membutuhkan tes API di setiap tahap, tetapi mengetahui pilihannya memungkinkan Anda memilih secara sengaja alih-alih membuang semuanya ke dalam satu pekerjaan pra-*deploy* yang besar.
Selama pengembangan: lokal dan pra-*commit*
Sebelum perubahan mencapai CI, pengembang harus dapat menjalankan tes API yang relevan terhadap lingkungan lokal atau dev. Ini adalah *feedback loop* tercepat yang Anda miliki. Menangkap bentuk respons yang rusak di sini berarti kode yang rusak bahkan tidak pernah di-push.
Dalam praktiknya ini adalah skenario yang sama yang akan Anda jalankan nanti di CI, hanya diarahkan ke lingkungan lokal. Anda membangunnya sekali. Jika Anda belum pernah membuatnya, cara menulis skenario pengujian dengan Apidog memandu Anda melalui permintaan berantai dan menarik nilai dari satu respons ke respons berikutnya.
Pada *pull request*: gerbang *merge*
Ini adalah tempat dengan nilai tertinggi untuk tes API, dan yang paling sering dilewatkan oleh tim. Ketika sebuah *pull request* dibuka, *pipeline* memulai layanan, menjalankan skenario API Anda terhadapnya, dan melaporkan berhasil atau gagal sebagai pemeriksaan status. Sebuah pemeriksaan yang gagal memblokir *merge*.
Alasan mengapa ini penting: biaya *bug* meningkat tajam semakin jauh ia berjalan. Kegagalan *assertion* pada PR adalah perbaikan lima menit bagi penulis, yang masih memiliki perubahan baru dalam benaknya. Kegagalan yang sama yang ditemukan seminggu kemudian di *staging* adalah proyek arkeologi. Menempatkan tes API pada gerbang PR adalah satu-satunya perubahan yang memindahkan cacat paling banyak ke kiri.
Setelah *build*, sebelum rilis: pemeriksaan integrasi dan kontrak
Setelah *artifact* dibangun dan di-*deploy* ke lingkungan *staging* atau integrasi, jalankan rangkaian yang lebih luas. Di sinilah Anda menguji *wiring* yang sebenarnya: apakah layanan pembayaran masih menerima *request body* layanan pesanan, apakah paginasi masih mengembalikan bidang yang dibaca klien Anda, apakah token autentikasi yang dikeluarkan oleh satu layanan diterima oleh yang lain.
Tahap ini juga tempat di mana pemikiran kontrak membuahkan hasil. Sebuah perubahan yang valid secara lokal masih dapat merusak konsumen *downstream*. Menjalankan seluruh set skenario terhadap lingkungan terintegrasi menangkap kerusakan antar-layanan yang secara struktural tidak dapat dilihat oleh *unit tests*. Pola-pola ini dibawa dari praktik otomatisasi pengujian API yang lebih luas.
Pada waktu *deploy*: *smoke tests*
Sebuah *deploy* tidak selesai ketika peluncuran selesai. Ia selesai ketika Anda memiliki bukti bahwa versi baru benar-benar melayani lalu lintas dengan benar. Sebuah *smoke test* adalah skenario kecil dan cepat yang mengenai jalur kritis tepat setelah *deploy*: dapatkah pengguna melakukan autentikasi, dapatkah mereka membaca data mereka, apakah *endpoint* kritis kesehatan mengembalikan 200 dengan bentuk yang benar.
Pertahankan rangkaian ini agar tetap kecil dan cepat. Tugasnya adalah sinyal *go* atau *no-go*, bukan cakupan. Jika gagal, Anda akan melakukan *rollback* secara otomatis. Jalankan skenario yang sama terhadap lingkungan produksi dengan menukar satu bendera lingkungan, tanpa duplikat pengujian untuk dipertahankan.
Dalam produksi: pemantauan berkelanjutan
Setelah *deploy*, lingkaran tidak berhenti. Skenario API yang sama yang Anda jalankan di CI dapat berjalan sesuai jadwal terhadap produksi sebagai pemantauan sintetis, menangkap ketergantungan pihak ketiga yang menurun atau sertifikat yang kedaluwarsa sebelum pelanggan melakukannya. Batas antara pengujian dan pemantauan sebagian besar adalah jadwal ia berjalan. Pemantauan API mencakup mengubah pengujian yang lulus menjadi sistem peringatan dini produksi.
Aturan praktis yang berguna di kelima tahap: semakin dekat ke produksi, semakin kecil dan cepat rangkaiannya. Cakupan luas pada PR dan dalam integrasi; rangkaian *smoke* yang tipis dan tanpa ampun pada *deploy* dan dalam pemantauan.
Mengapa lapisan API mendapatkan tempatnya di *pipeline*
Penting untuk menjadi konkret tentang mengapa tes API layak mendapatkan tempat utama di atas menumpuk lebih banyak beban pada tes UI.
Mereka cepat. Skenario API berkomunikasi langsung dengan HTTP. Tidak ada peramban yang harus dinyalakan, tidak ada DOM yang harus ditunggu, tidak ada Chrome *headless* yang *flaking* pada *render* yang lambat. Sebuah skenario yang menjalankan selusin *endpoint* selesai dalam hitungan detik, yang memungkinkan Anda menjalankannya pada setiap *commit* tanpa orang-orang belajar mengabaikan pekerjaan sepuluh menit.
Mereka stabil. Tes UI rusak ketika nama kelas berubah atau elemen di-*render* ulang satu *frame* terlambat. Tes API hanya rusak ketika kontrak yang sebenarnya berubah, yang justru saat Anda ingin mengetahuinya. Lebih sedikit *flake* berarti orang percaya pada *build* yang merah, dan *build* yang dipercaya orang adalah satu-satunya *build* yang menghalangi sesuatu.
Mereka menguji apa yang terintegrasi. Aplikasi seluler Anda, integrasi mitra Anda, *microservices* Anda sendiri semuanya bergantung pada kontrak API, bukan pada CSS Anda. Ketika kontrak itu berubah secara diam-diam, setiap konsumen rusak secara bersamaan. Tes API adalah lapisan yang menangkapnya.
Inilah mengapa pertanyaan *pipeline* sebenarnya adalah pertanyaan API. Anda dapat memiliki rangkaian *unit test* yang menyeluruh dan rangkaian UI yang cantik dan tetap mengirimkan *bug* pembayaran Jumat sore, karena tidak ada lapisan yang mengawasi titik pertemuan layanan.
Menyambungkan tes API ke *pipeline* dengan Apidog CLI
Mekanisnya penting, karena tes yang ada tetapi tidak berjalan secara otomatis tidak menangkap apa pun. Polanya sama di setiap sistem CI: instal *runner*, arahkan ke tes Anda, biarkan *exit code*-nya memutuskan apakah *build* lulus.
Dengan Apidog, Anda tidak menulis ulang tes Anda sebagai kode. Anda membangun skenario sekali di aplikasi, lalu Apidog CLI menjalankan skenario yang sama itu secara *headless*. CLI adalah paket npm, jadi *runner* CI mana pun dengan Node.js dapat menggunakannya.
Instal:
npm install -g apidog-cli
Lalu jalankan skenario. Anda membuat token akses dan menemukan ID skenario dan lingkungan di dalam tab CI/CD skenario pengujian di Apidog, yang membangun perintah lengkap untuk Anda salin:
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t 605067 \
-e 1629989 \
-r cli
Beberapa hal melakukan pekerjaan nyata di sini. *Flag* -t menamai skenario berdasarkan ID; ganti dengan -f <folderId> untuk menjalankan seluruh folder, atau --test-suite <id> untuk menjalankan rangkaian pengujian yang dikurasi sebagai satu pekerjaan. *Flag* -e memilih lingkungan, yaitu bagaimana skenario yang sama mengunci PR terhadap *staging* dan *smoke-tests* terhadap produksi tanpa duplikat. *Flag* -r memilih *reporter*; cli mencetak ke *log*, dan junit mengeluarkan XML yang dapat dirender oleh *dashboard* CI Anda sebagai laporan pengujian.
Bagian yang menjadikannya gerbang adalah *exit code*. Ketika setiap *assertion* lulus, apidog run keluar dengan 0. Ketika ada yang gagal, ia keluar dengan non-nol. Sistem CI Anda membaca kode itu, menandai langkah gagal, dan memblokir *merge* atau *deploy*. Anda tidak mengkonfigurasi gerbang terpisah; *exit code* adalah gerbangnya. Jalankan apidog run --help untuk melihat semua *flag* yang tersedia untuk versi Anda.
Berikut adalah tahap gerbang PR yang dihubungkan ke GitHub Actions:
name: API Tests
on: [pull_request]
jobs:
api-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Apidog CLI
run: npm install -g apidog-cli
- name: Run API scenarios
env:
APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
run: |
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 605067 \
-e 1629989 \
-r cli,junit
Token tersimpan di rahasia repositori dan mencapai langkah melalui env:, tidak pernah di-*hard-code*. Blok yang sama dapat dimasukkan ke GitLab CI, Jenkins, CircleCI, atau Azure Pipelines dengan sintaks platform tersebut di sekitarnya, karena satu-satunya ketergantungan nyata adalah Node. Panduan khusus platform mencakup detailnya: mengotomatiskan tes API di GitHub Actions dan mengintegrasikan tes Apidog dengan Jenkins.
Untuk tahap *smoke test* saat *deploy*, perintahnya hampir tidak berubah. Anda mengarahkannya ke ID lingkungan produksi dan menjaga skenario tetap kecil:
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e $PROD_ENV_ID -r cli
Satu skenario, satu pertukaran lingkungan, dua pekerjaan. Itulah daya tarik utama dari membuat tes sekali dan menjalankannya di seluruh siklus hidup.
Kesalahan umum yang secara diam-diam menggagalkan gerbang
Sebuah *pipeline* dapat terlihat sepenuhnya otomatis dan tetap tidak menangkap apa pun. Perhatikan hal-hal berikut.
Menelan *exit code*. Seseorang membungkus perintah pengujian dalam *shell pipeline* atau menambahkan || true untuk "menghentikannya agar tidak merusak *build*." Itu juga menghentikannya agar tidak menangkap apa pun. *Build* akan selalu hijau. Jangan pernah menutupi *exit* non-nol *runner*; *exit* itulah intinya.
Hanya menguji jalur bahagia (*happy path*). Skenario yang hanya mengkonfirmasi 200 OK dan berhenti di situ melewatkan kerusakan yang penting. Tegaskan pada bentuk *body* respons, tipe bidang, respons kesalahan untuk *input* yang buruk. Asersi API mencakup validasi lebih dari sekadar kode status.
Satu pekerjaan besar pra-*deploy*. Memadatkan setiap pengujian ke dalam satu tahap tepat sebelum rilis menggagalkan *shift-left*. Anda mengetahui tentang kontrak yang rusak beberapa menit sebelum pengiriman alih-alih pada PR. Sebarkan rangkaian pengujian di seluruh tahap: luas pada PR, tipis pada *deploy*.
Menguji terhadap lingkungan *mutable* yang dibagikan. Ketika dua *pipeline* mengenai basis data yang sama, penulisan dari satu *run* meracuni pembacaan dari *run* lain, dan Anda mendapatkan kegagalan *flaky* yang mengikis kepercayaan. Gunakan lingkungan yang terisolasi, atau gunakan mocking API untuk menggantikan ketergantungan yang tidak Anda kontrol sehingga *downtime* pihak ketiga tidak membuat *build* Anda merah.
Melupakan laporan saat kegagalan. Jika laporan Anda hanya diunggah ketika pengujian lulus, Anda tidak akan pernah melihat laporan saat Anda membutuhkannya. Konfigurasi pengunggahan *artifact* agar berjalan bahkan saat kegagalan.
FAQ
Di mana dalam *pipeline* DevOps tes API harus dijalankan?
Setidaknya, pada *pull request* sebagai gerbang *merge*, karena itu menangkap cacat paling banyak dengan biaya terendah. Idealnya juga setelah *build* terhadap lingkungan terintegrasi untuk pemeriksaan kontrak, dan sebagai rangkaian *smoke test* kecil segera setelah *deploy*. Skenario Apidog yang sama berjalan di setiap tahap; Anda hanya mengubah *flag* lingkungan. Tim yang menjalankan Apidog tanpa Postman mengikuti *staging* yang sama.
Apa perbedaan antara otomatisasi tes API dan CI/CD?
CI/CD adalah *pipeline* yang membangun, menguji, dan mengirimkan kode Anda secara otomatis. Otomatisasi tes API adalah salah satu jenis pengujian yang berjalan di dalam *pipeline* tersebut. CI/CD adalah sabuk konveyor; tes API otomatis adalah stasiun kualitas di dalamnya. Jika istilah CI/CD itu sendiri tidak jelas, apa itu CI/CD mencakup dasar-dasarnya.
Apakah saya perlu menulis ulang tes API saya sebagai kode untuk menjalankannya di CI?
Tidak dengan Apidog. Anda membangun skenario pengujian secara visual di aplikasi, dan Apidog CLI menjalankan skenario yang sama itu secara *headless*. CLI adalah paket npm, jadi *runner* CI mana pun yang terinstal Node.js dapat menjalankannya dengan satu perintah.
Bagaimana tes API menggagalkan *build*?
Melalui *exit code*. Ketika setiap *assertion* dalam sebuah skenario lulus, *runner* keluar dengan 0. Ketika ada *assertion* yang gagal, ia keluar dengan non-nol. Sistem CI membaca kode itu, menandai langkah gagal, dan memblokir *merge* atau *deploy*. Tidak diperlukan konfigurasi gerbang terpisah.
Haruskah tes performa berjalan di *pipeline* yang sama?
Pertahankan tes API fungsional pada setiap PR dan jalankan beban yang lebih berat serta pengujian performa pada jadwal terpisah, seperti setiap malam. *Run* performa membutuhkan waktu lebih lama dan memerlukan lingkungan yang stabil, sehingga menggabungkannya ke setiap *commit* memperlambat *feedback* tanpa menambahkan banyak sinyal per-*commit*.
Di mana menempatkan tes API pertama Anda
Otomatisasi pengujian dalam DevOps bukanlah satu gerbang yang Anda bangun sekali. Ini adalah tes API yang ditempatkan secara sengaja di seluruh lingkaran: di mesin pengembang untuk *feedback* cepat, pada *pull request* sebagai gerbang *merge* yang menangkap paling banyak, setelah *build* untuk pemeriksaan kontrak, saat *deploy* sebagai sinyal *smoke*, dan dalam produksi sebagai monitor. Lapisan API mendapatkan *real estate pipeline* paling banyak karena cepat, stabil, dan menguji sambungan di mana sistem sebenarnya rusak.
Jika tes API Anda masih berupa langkah-langkah yang dapat diklik yang dijalankan seseorang secara manual, celah yang harus ditutup adalah gerbang *merge*. Unduh Apidog, bangun satu skenario, salin perintah apidog run dari tab CI/CD-nya, dan tempelkan blok GitHub Actions di atas. Anda akan memiliki tes API yang memblokir *merge* yang rusak pada akhir sore hari, dan *bug* *deploy* Jumat akan berubah merah pada *pull request* alih-alih di antrean dukungan Anda.
