Cara Menjalankan Tes Otomatis dengan GitHub Actions
Pendahuluan
Bayangkan kamu sedang membangun fitur baru di aplikasimu. Setelah selesai coding, kamu harus memastikan semua fitur lama masih berjalan dengan baik. Kalau dilakukan manual, ini bisa memakan waktu berjam-jam. Nah, di sinilah tes otomatis (automated testing) berperan.
Dengan GitHub Actions, kamu bisa mengatur agar setiap kali ada kode baru yang di-push ke repositori, tes akan berjalan secara otomatis tanpa perlu kamu jalankan secara manual. Seperti punya asisten yang selalu siap memeriksa pekerjaanmu setiap saat.
Artikel ini akan memandu kamu dari nol — mulai dari menyiapkan proyek hingga workflow GitHub Actions yang menjalankan tes otomatis. Jika kamu ingin membangun aplikasi berskala besar seperti Tokopedia atau Shopee, pola ini adalah fondasi dari proses delivery yang andal.
Prasyarat: Menyiapkan Proyek dan Repositori
Sebelum mulai, pastikan kamu sudah memiliki:
- Akun GitHub dan repositori yang aktif
- Node.js atau Python terinstal di komputer lokal
- Pemahaman dasar tentang Git (commit, push, pull)
- Proyek dengan unit test yang sudah bisa dijalankan secara lokal
Untuk artikel ini, kita akan menggunakan proyek Node.js dengan Jest sebagai contoh utama, dengan tambahan contoh Python menggunakan pytest.
Menyiapkan Proyek Node.js dengan Jest
Buat proyek baru atau gunakan proyek yang sudah ada:
mkdir my-tested-app
cd my-tested-app
npm init -y
npm install --save-dev jest
Tambahkan script test di package.json:
{
"name": "my-tested-app",
"version": "1.0.0",
"scripts": {
"test": "jest"
},
"devDependencies": {
"jest": "^29.0.0"
}
}
Buat file fungsi sederhana (src/calculator.js):
function tambah(a, b) {
return a + b;
}
function kurang(a, b) {
return a - b;
}
module.exports = { tambah, kurang };
Lalu buat file test-nya (src/calculator.test.js):
const { tambah, kurang } = require('./calculator');
test('tambah 2 + 3 harus menghasilkan 5', () => {
expect(tambah(2, 3)).toBe(5);
});
test('kurang 10 - 4 harus menghasilkan 6', () => {
expect(kurang(10, 4)).toBe(6);
});
Coba jalankan dulu secara lokal untuk memastikan berhasil:
npm test
Jika semua tes hijau (pass), kita siap lanjut ke GitHub Actions!
Membuat File Workflow GitHub Actions
GitHub Actions membaca instruksi dari file YAML yang disimpan di folder .github/workflows/. Kamu bisa membayangkan file ini seperti resep masakan — GitHub Actions akan mengikuti langkah-langkahnya secara berurutan.
Buat folder dan file berikut:
mkdir -p .github/workflows
touch .github/workflows/run-tests.yml
Isi file run-tests.yml dengan konfigurasi berikut:
name: Jalankan Tes Otomatis
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout kode
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependensi
run: npm ci
- name: Jalankan tes
run: npm test
Mari kita bedah baris demi baris:
name: Nama workflow yang akan muncul di tab Actions GitHubon: Kapan workflow ini dipicu — saat push ke branchmain/develop, atau saat ada pull request kemainjobs: Daftar pekerjaan yang akan dijalankanruns-on: ubuntu-latest: Workflow berjalan di mesin virtual Ubuntu terbarusteps: Langkah-langkah yang dieksekusi secara berurutan
Mengonfigurasi Job untuk Menjalankan Tes Otomatis
Kita bisa memperkuat konfigurasi di atas dengan beberapa fitur tambahan yang berguna.
Menguji di Berbagai Versi Node.js (Matrix Strategy)
Kalau aplikasimu harus berjalan di beberapa versi Node.js, gunakan matrix strategy:
name: Tes Multi-Versi Node.js
on:
push:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test
Dengan konfigurasi ini, GitHub Actions akan menjalankan tes secara paralel di Node.js 18, 20, dan 22 sekaligus.
Menyimpan Hasil Test Coverage
Untuk melihat seberapa banyak kode yang sudah diuji, tambahkan laporan coverage:
- name: Jalankan tes dengan coverage
run: npm test -- --coverage
- name: Upload laporan coverage
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
Contoh untuk Python dengan pytest
Jika proyekmu menggunakan Python, berikut contoh workflownya:
name: Tes Python
on:
push:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependensi
run: |
python -m pip install --upgrade pip
pip install pytest
pip install -r requirements.txt
- name: Jalankan tes
run: pytest tests/ -v
Konsep penggunaan pip install di sini mirip dengan cara kamu belajar mengelola modul di Python — jika kamu ingin memperdalam pemahaman tentang scripting Python, baca juga Mengenal Dasar Python untuk Pemrograman Aplikasi CLI.
Contoh Kasus Nyata
Mari kita lihat skenario yang lebih realistis: sebuah API sederhana dengan Express.js yang memiliki endpoint dan tes integrasi.
Struktur proyek:
my-api/
├── src/
│ └── app.js
├── tests/
│ └── app.test.js
├── package.json
└── .github/
└── workflows/
└── ci.yml
File src/app.js:
const express = require('express');
const app = express();
app.get('/status', (req, res) => {
res.json({ status: 'ok', message: 'API berjalan normal' });
});
app.get('/hitung/:a/:b', (req, res) => {
const a = parseInt(req.params.a);
const b = parseInt(req.params.b);
res.json({ hasil: a + b });
});
module.exports = app;
File tests/app.test.js:
const request = require('supertest');
const app = require('../src/app');
describe('Endpoint /status', () => {
it('harus mengembalikan status ok', async () => {
const res = await request(app).get('/status');
expect(res.statusCode).toBe(200);
expect(res.body.status).toBe('ok');
});
});
describe('Endpoint /hitung', () => {
it('harus menghitung 3 + 7 = 10', async () => {
const res = await request(app).get('/hitung/3/7');
expect(res.statusCode).toBe(200);
expect(res.body.hasil).toBe(10);
});
});
Workflow CI lengkap (ci.yml):
name: CI — Tes dan Validasi
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
name: Jalankan Test Suite
runs-on: ubuntu-latest
steps:
- name: Checkout repositori
uses: actions/checkout@v4
- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install semua dependensi
run: npm ci
- name: Jalankan linting (opsional)
run: npm run lint --if-present
- name: Jalankan unit test
run: npm test
- name: Notifikasi hasil
if: failure()
run: echo "Ada tes yang gagal! Periksa log di atas."
Setiap kali kamu push kode baru, workflow ini akan berjalan otomatis. Jika ada tes yang gagal, kamu akan melihat tanda silang merah (❌) di commit tersebut — sangat membantu saat bekerja dalam tim. Ini mirip dengan prinsip modularitas dalam JavaScript modern yang juga berlaku untuk kode yang mudah diuji — jika kamu belum familiar, simak Mastering ES6 Modules: Cara Mengelola Kode JavaScript Secara Terstruktur.
Troubleshooting: Error yang Sering Muncul
npm ci gagal dengan error “missing package-lock.json”
Penyebab: Perintah npm ci membutuhkan file package-lock.json yang harus sudah ada di repositori. Jika file ini tidak di-commit ke Git, workflow akan gagal.
Solusi:
# Jalankan di lokal untuk membuat lock file
npm install
# Pastikan file ini masuk ke Git
git add package-lock.json
git commit -m "chore: tambahkan package-lock.json"
git push
Tes gagal di GitHub Actions tapi lolos di lokal
Penyebab: Biasanya disebabkan oleh perbedaan versi Node.js antara mesin lokal dan runner GitHub, atau variabel environment yang tidak dikonfigurasi di workflow.
Solusi:
# Pastikan versi Node.js sama persis
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x' # Gunakan versi yang sama dengan lokal
# Tambahkan env variable yang dibutuhkan
- name: Jalankan tes
run: npm test
env:
NODE_ENV: test
DATABASE_URL: ${{ secrets.DATABASE_URL }}
Workflow tidak terpicu saat push
Penyebab: Nama branch di konfigurasi on.push.branches tidak sesuai dengan nama branch yang digunakan, atau file workflow disimpan di path yang salah.
Solusi:
# Periksa nama branch — pastikan sesuai
on:
push:
branches:
- main # bukan 'master' jika branch utamamu 'main'
- develop
# Pastikan file disimpan di path yang benar:
# .github/workflows/nama-file.yml ← BENAR
# github/workflows/nama-file.yml ← SALAH (kurang titik di depan)
Error “Process completed with exit code 1” tanpa pesan jelas
Penyebab: Salah satu tes gagal, tapi output-nya terpotong atau tidak terlihat di log summary.
Solusi:
# Tambahkan flag verbose untuk melihat detail error
- name: Jalankan tes dengan detail
run: npm test -- --verbose
# Untuk Jest, bisa juga tambahkan:
- name: Jalankan tes
run: npx jest --no-coverage --verbose --forceExit
Pertanyaan yang Sering Diajukan
Apa perbedaan antara npm install dan npm ci di workflow?
npm ci dirancang khusus untuk environment CI/CD. Bedanya, npm ci selalu menghapus folder node_modules terlebih dahulu lalu menginstall ulang persis sesuai package-lock.json — tidak ada toleransi untuk versi yang berbeda. Ini membuat build lebih konsisten dan reproducible dibanding npm install yang mungkin mengupdate versi minor secara otomatis.
Apakah tes otomatis bisa dihentikan agar tidak berjalan untuk commit tertentu?
Ya, bisa! Kamu cukup tambahkan [skip ci] atau [ci skip] di pesan commit-mu. GitHub Actions akan membaca tanda ini dan melewati eksekusi workflow.
git commit -m "chore: update README [skip ci]"
Bagaimana cara menyimpan variabel rahasia (API key, password) di GitHub Actions?
Gunakan fitur GitHub Secrets. Masuk ke repositorimu → Settings → Secrets and variables → Actions → klik “New repository secret”. Lalu panggil di workflow dengan sintaks ${{ secrets.NAMA_SECRET }}. Nilai secret tidak akan pernah muncul di log.
Apakah saya bisa menjalankan workflow secara manual tanpa harus push kode?
Bisa! Tambahkan workflow_dispatch di bagian on workflow-mu:
on:
push:
branches: [ main ]
workflow_dispatch: # Tambahkan ini
Setelah itu, kamu bisa menjalankan workflow kapan saja dari tab Actions di repositori GitHub-mu dengan menekan tombol “Run workflow”.
Berapa lama workflow GitHub Actions bisa berjalan secara gratis?
Untuk repositori publik, GitHub Actions gratis tanpa batas. Untuk repositori privat, akun gratis mendapat 2.000 menit per bulan. Jika tes unit sederhana, biasanya satu run hanya memakan 1-3 menit — lebih dari cukup untuk proyek personal atau tim kecil.
Kesimpulan
Kamu sudah berhasil mempelajari cara menjalankan tes otomatis dengan GitHub Actions! Mulai dari menyiapkan proyek Node.js dengan Jest, membuat file workflow YAML, mengonfigurasi job dengan matrix strategy, hingga menangani error umum yang sering muncul.
Kunci utamanya adalah: buat tes dulu secara lokal sampai bisa berjalan, lalu bungkus dalam workflow GitHub Actions agar berjalan otomatis setiap kali ada perubahan kode. Dengan pola ini, kamu bisa tidur nyenyak karena tahu bahwa setiap push ke repositori sudah “dijaga” oleh tes otomatis.
Selamat belajar dan terus berlatih! Automasi testing adalah kebiasaan kecil yang dampaknya luar biasa bagi kualitas proyek jangka panjang — jangan ragu untuk eksplorasi artikel-artikel lainnya di KamusNgoding dan tingkatkan skill DevOps-mu selangkah demi selangkah.