Selective Test Execution dengan Playwright menggunakan GitHub Actions: Panduan Lengkap
Pengujian adalah bagian integral dari siklus hidup pengembangan perangkat lunak (SDLC). Memastikan bahwa aplikasi Anda berperilaku seperti yang diharapkan adalah kunci untuk memberikan pengalaman pengguna yang berkualitas tinggi. Namun, menjalankan semua pengujian pada setiap komit bisa memakan waktu dan sumber daya, terutama untuk proyek besar dengan banyak pengujian. Di sinilah eksekusi pengujian selektif berperan. Artikel ini akan membahas cara menerapkan mekanisme eksekusi pengujian selektif dengan Playwright dan GitHub Actions, memungkinkan Anda menjalankan hanya pengujian yang relevan berdasarkan perubahan kode.
Mengapa Eksekusi Pengujian Selektif?
Sebelum kita menyelami implementasi teknis, mari kita pahami mengapa eksekusi pengujian selektif penting:
- Menghemat Waktu: Jalankan hanya pengujian yang terpengaruh oleh perubahan kode Anda, mengurangi waktu build secara signifikan.
- Menghemat Sumber Daya: Kurangi penggunaan sumber daya komputasi dengan menghindari eksekusi pengujian yang tidak perlu.
- Umpan Balik Lebih Cepat: Dapatkan umpan balik pengujian yang lebih cepat, memungkinkan Anda mengidentifikasi dan memperbaiki masalah lebih awal dalam siklus pengembangan.
- Optimasi CI/CD: Optimalkan alur CI/CD Anda dengan membuat build lebih efisien dan hemat biaya.
- Fokus pada Risiko: Prioritaskan pengujian yang mencakup area kode yang berisiko lebih tinggi karena perubahan terbaru.
Prasyarat
Sebelum memulai, pastikan Anda memiliki yang berikut:
- Akun GitHub: Anda akan membutuhkan akun GitHub untuk menyimpan kode Anda dan mengkonfigurasi GitHub Actions.
- Node.js dan npm (atau yarn): Playwright adalah framework Node.js, jadi Anda memerlukan Node.js dan npm (atau yarn) terinstal.
- Playwright Terinstal: Pastikan Playwright terinstal di proyek Anda.
- Pemahaman Dasar tentang Playwright: Keakraban dengan dasar-dasar Playwright, seperti menulis pengujian, menjalankan pengujian, dan konfigurasi.
- Pemahaman Dasar tentang GitHub Actions: Keakraban dengan dasar-dasar GitHub Actions, seperti membuat alur kerja, menggunakan pemicu, dan menjalankan perintah.
Langkah-Langkah Implementasi Eksekusi Pengujian Selektif
Berikut adalah langkah-langkah untuk menerapkan eksekusi pengujian selektif dengan Playwright menggunakan GitHub Actions:
1. Struktur Proyek
Organisasikan proyek Anda dengan cara yang logis, memisahkan pengujian berdasarkan fungsionalitas atau fitur. Ini akan membuat lebih mudah untuk mengidentifikasi pengujian mana yang terpengaruh oleh perubahan tertentu.
Contoh struktur proyek:
project-root/
src/
components/
button.js
form.js
pages/
home.js
login.js
tests/
components/
button.spec.js
form.spec.js
pages/
home.spec.js
login.spec.js
e2e/
checkout.spec.js
.github/workflows/
ci.yml
package.json
playwright.config.js
2. Membuat Skrip untuk Mengidentifikasi Pengujian yang Terpengaruh
Kita memerlukan skrip yang akan mengidentifikasi pengujian mana yang perlu dijalankan berdasarkan file yang diubah dalam komit. Skrip ini akan menganalisis daftar file yang diubah dan memetakan file tersebut ke pengujian yang sesuai.
Berikut adalah contoh skrip Node.js (scripts/find-affected-tests.js
):
“`javascript
// scripts/find-affected-tests.js
const { execSync } = require(‘child_process’);
const fs = require(‘fs’);
const path = require(‘path’);
function getChangedFiles() {
try {
const output = execSync(‘git diff –name-only –relative HEAD HEAD^’).toString().trim();
return output ? output.split(‘\n’) : [];
} catch (error) {
console.error(‘Error getting changed files:’, error);
return [];
}
}
function mapFilesToTests(changedFiles) {
const testFiles = new Set();
changedFiles.forEach(file => {
// Logika untuk memetakan file yang diubah ke file pengujian yang sesuai.
// Contoh: Jika file yang diubah adalah ‘src/components/button.js’,
// tambahkan ‘tests/components/button.spec.js’ ke daftar pengujian.
// Contoh sederhana: asumsikan pengujian memiliki struktur yang sama dengan kode sumber
if (file.startsWith(‘src/’)) {
const testFile = file.replace(/^src\/(.*)\.(js|ts|jsx|tsx)$/, ‘tests/$1.spec.js’);
if (fs.existsSync(testFile)) {
testFiles.add(testFile);
} else {
console.warn(`Warning: Could not find test file for ${file}`);
}
}
//Contoh untuk menangani perubahan di folder e2e
if (file.startsWith(‘e2e/’)) {
const testFile = file;
if(fs.existsSync(testFile)) {
testFiles.add(testFile);
} else {
console.warn(`Warning: Could not find test file for ${file}`);
}
}
});
return Array.from(testFiles);
}
const changedFiles = getChangedFiles();
const affectedTests = mapFilesToTests(changedFiles);
console.log(JSON.stringify(affectedTests));
“`
Penjelasan:
getChangedFiles()
: Menggunakangit diff
untuk mendapatkan daftar file yang telah diubah antara komit saat ini (HEAD
) dan komit induknya (HEAD^
).mapFilesToTests(changedFiles)
: Fungsi ini menerima daftar file yang diubah dan memetakannya ke file pengujian yang sesuai. Logika pemetaan akan sangat bergantung pada struktur proyek Anda. Contoh yang disediakan mengasumsikan bahwa file pengujian berada di direktoritests/
dengan struktur yang sama dengan kode sumber disrc/
, dengan ekstensi.spec.js
.console.log(JSON.stringify(affectedTests))
: Mencetak daftar pengujian yang terpengaruh sebagai string JSON. Ini penting karena kita akan menggunakan output ini di GitHub Actions.
Penting: Sesuaikan fungsi mapFilesToTests
agar sesuai dengan struktur proyek Anda. Anda mungkin perlu menambahkan logika yang lebih kompleks untuk menangani skenario yang berbeda.
3. Mengonfigurasi GitHub Actions Workflow
Sekarang, kita akan membuat alur kerja GitHub Actions yang akan:
- Memeriksa kode.
- Menginstal dependensi Node.js.
- Menjalankan skrip
find-affected-tests.js
untuk mengidentifikasi pengujian yang terpengaruh. - Menjalankan Playwright hanya pada pengujian yang terpengaruh.
Buat file .github/workflows/ci.yml
dengan konten berikut:
“`yaml
# .github/workflows/ci.yml
name: CI – Selective Testing
on:
push:
branches: [ “main” ]
pull_request:
branches: [ “main” ]
jobs:
test:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v3
with:
fetch-depth: 2 # Penting untuk mendapatkan perubahan antara komit
– name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
– name: Install dependencies
run: npm install
– name: Find affected tests
id: find-tests
run: |
TESTS=$(node scripts/find-affected-tests.js)
echo “affected_tests=$TESTS” >> $GITHUB_OUTPUT
– name: Run Playwright tests
if: steps.find-tests.outputs.affected_tests != ‘[]’
run: |
AFFECTED_TESTS=”${{ steps.find-tests.outputs.affected_tests }}”
echo “Running only affected tests: $AFFECTED_TESTS”
npx playwright test –reporter=html $AFFECTED_TESTS
– name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/
retention-days: 30
“`
Penjelasan:
on
: Alur kerja dipicu pada setiappush
danpull_request
ke cabangmain
.actions/checkout@v3
: Memeriksa kode ke lingkungan GitHub Actions.fetch-depth: 2
penting untuk mendapatkan riwayat komit dan mengizinkangit diff
untuk bekerja dengan benar.actions/setup-node@v3
: Menyiapkan lingkungan Node.js.npm install
: Menginstal dependensi proyek.Find affected tests
:- Menjalankan skrip
scripts/find-affected-tests.js
. - Menangkap output dari skrip dan menyimpannya sebagai variabel
affected_tests
dalam output langkah menggunakan sintaksecho "affected_tests=$TESTS" >> $GITHUB_OUTPUT
.
- Menjalankan skrip
Run Playwright tests
:if: steps.find-tests.outputs.affected_tests != '[]'
: Kondisi ini memastikan bahwa pengujian Playwright hanya dijalankan jika ada pengujian yang terpengaruh (yaitu, jika outputaffected_tests
tidak kosong).AFFECTED_TESTS="${{ steps.find-tests.outputs.affected_tests }}"
: Mengambil daftar pengujian yang terpengaruh dari output langkah sebelumnya.npx playwright test --reporter=html $AFFECTED_TESTS
: Menjalankan Playwright hanya pada pengujian yang terpengaruh. Parameter--reporter=html
menghasilkan laporan HTML.
Upload Playwright report
:if: always()
: Laporan diunggah terlepas dari apakah pengujian berhasil atau gagal.- Mengunggah laporan Playwright sebagai artefak, membuatnya tersedia untuk diunduh dan diperiksa.
4. Memperbarui package.json
Pastikan skrip find-affected-tests.js
dapat dieksekusi. Anda dapat menambahkan skrip di package.json
untuk memudahkan eksekusi:
“`json
{
“name”: “my-project”,
“version”: “1.0.0”,
“scripts”: {
“find-affected-tests”: “node scripts/find-affected-tests.js”
},
“devDependencies”: {
“@playwright/test”: “^1.37.0”
}
}
“`
Dengan ini, Anda dapat menjalankan skrip dengan npm run find-affected-tests
.
5. Uji Implementasi
Untuk menguji implementasi Anda:
- Buat perubahan pada file sumber (misalnya,
src/components/button.js
). - Komit dan dorong perubahan Anda ke cabang
main
. - Periksa alur kerja GitHub Actions. Seharusnya hanya menjalankan pengujian yang terkait dengan file
button.js
(misalnya,tests/components/button.spec.js
). - Buat perubahan pada file yang tidak memiliki pengujian terkait. Seharusnya tidak ada pengujian yang dijalankan.
Peningkatan Lebih Lanjut
Berikut adalah beberapa cara untuk meningkatkan implementasi eksekusi pengujian selektif Anda:
- Cakupan Kode: Integrasikan alat cakupan kode untuk menentukan dengan tepat baris kode mana yang tercakup oleh pengujian mana. Ini memungkinkan pemetaan yang lebih akurat dari perubahan ke pengujian.
- Caching: Cache dependensi Node.js dan browser Playwright untuk mempercepat waktu build.
- Paralelisasi: Paralelkan eksekusi pengujian untuk lebih mengurangi waktu build.
- Matrix Builds: Gunakan matrix builds untuk menjalankan pengujian di beberapa browser dan konfigurasi secara paralel.
- Analisis Dampak Perubahan Tingkat Lanjut: Gunakan alat yang lebih canggih untuk analisis dampak perubahan, yang mempertimbangkan dependensi kode dan hubungan untuk mengidentifikasi pengujian yang terpengaruh dengan lebih akurat.
- Integrasi dengan Sistem Manajemen Pengujian: Integrasikan dengan sistem manajemen pengujian untuk melacak hasil pengujian dan mengidentifikasi area kode yang tidak tercakup oleh pengujian.
Contoh Kasus: Implementasi Tingkat Lanjut dengan Cakupan Kode
Mari kita pertimbangkan contoh yang lebih canggih yang menggabungkan cakupan kode untuk mencapai eksekusi pengujian yang lebih presisi.
1. Instalasi Cakupan Kode
Pertama, kita akan menginstal nyc
, alat cakupan kode yang populer, dan mengkonfigurasi Playwright untuk menggunakannya.
“`bash
npm install nyc –save-dev
“`
2. Konfigurasi Playwright
Perbarui file playwright.config.js
Anda untuk mengintegrasikan dengan nyc
:
“`javascript
// playwright.config.js
const config = {
use: {
// … konfigurasi Playwright lainnya …
coverage: {
enabled: true, // Aktifkan cakupan kode
reporter: [‘html’, ‘text’], // Konfigurasi laporan
},
},
reporter: ‘html’,
};
module.exports = config;
“`
3. Memperbarui Skrip Pengujian
Perbarui skrip pengujian Anda di package.json
untuk menggunakan nyc
:
“`json
{
“scripts”: {
“test”: “nyc playwright test”,
“coverage”: “nyc report”,
“find-affected-tests”: “node scripts/find-affected-tests.js”
}
}
“`
4. Memperbarui find-affected-tests.js
Skrip yang diperbarui akan menganalisis laporan cakupan kode untuk menentukan pengujian mana yang mencakup file yang diubah.
“`javascript
// scripts/find-affected-tests.js
const { execSync } = require(‘child_process’);
const fs = require(‘fs’);
const path = require(‘path’);
function getChangedFiles() {
try {
const output = execSync(‘git diff –name-only –relative HEAD HEAD^’).toString().trim();
return output ? output.split(‘\n’) : [];
} catch (error) {
console.error(‘Error getting changed files:’, error);
return [];
}
}
function mapFilesToTests(changedFiles) {
const testFiles = new Set();
const coverageData = loadCoverageData();
changedFiles.forEach(file => {
Object.keys(coverageData).forEach(testFile => {
const fileCoverage = coverageData[testFile].files;
if (fileCoverage[file]) {
testFiles.add(testFile);
}
});
});
return Array.from(testFiles);
}
function loadCoverageData() {
try {
const rawData = fs.readFileSync(‘.nyc_output/out.json’, ‘utf-8’);
return JSON.parse(rawData);
} catch (error) {
console.error(‘Error loading coverage data:’, error);
return {};
}
}
const changedFiles = getChangedFiles();
const affectedTests = mapFilesToTests(changedFiles);
console.log(JSON.stringify(affectedTests));
“`
Penjelasan:
loadCoverageData()
: Fungsi ini memuat data cakupan dari file.nyc_output/out.json
, yang dihasilkan olehnyc
.mapFilesToTests(changedFiles)
: Fungsi ini sekarang menggunakan data cakupan untuk menentukan pengujian mana yang mencakup file yang diubah. Ini memeriksa setiap file yang diubah terhadap data cakupan dan menambahkan pengujian yang mencakup file itu ke daftar pengujian yang terpengaruh.
5. Memperbarui Workflow GitHub Actions
Perbarui alur kerja GitHub Actions Anda untuk menjalankan cakupan dan mengidentifikasi pengujian yang terpengaruh berdasarkan data cakupan.
“`yaml
name: CI – Selective Testing with Coverage
on:
push:
branches: [ “main” ]
pull_request:
branches: [ “main” ]
jobs:
test:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v3
with:
fetch-depth: 2
– name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
– name: Install dependencies
run: npm install
– name: Run tests with coverage
run: npm run test
– name: Generate coverage report
run: npm run coverage
– name: Find affected tests
id: find-tests
run: |
TESTS=$(node scripts/find-affected-tests.js)
echo “affected_tests=$TESTS” >> $GITHUB_OUTPUT
– name: Run Playwright tests
if: steps.find-tests.outputs.affected_tests != ‘[]’
run: |
AFFECTED_TESTS=”${{ steps.find-tests.outputs.affected_tests }}”
echo “Running only affected tests: $AFFECTED_TESTS”
npx playwright test –reporter=html $AFFECTED_TESTS
– name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/
retention-days: 30
– name: Upload coverage report
if: always()
uses: actions/upload-artifact@v3
with:
name: coverage-report
path: coverage-report
retention-days: 30
“`
Perubahan Penting:
Run tests with coverage
: Ini menjalankan semua pengujian dengan cakupan kode diaktifkan.Generate coverage report
: Ini menghasilkan laporan cakupan.- Skrip
find-affected-tests.js
sekarang menggunakan data cakupan untuk menentukan pengujian yang terpengaruh.
Kesimpulan
Eksekusi pengujian selektif adalah teknik yang berharga untuk mengoptimalkan alur CI/CD Anda dan mempercepat siklus umpan balik. Dengan menggabungkan Playwright dan GitHub Actions, Anda dapat menerapkan mekanisme yang kuat yang menjalankan hanya pengujian yang relevan berdasarkan perubahan kode. Ini menghemat waktu, sumber daya, dan memungkinkan Anda untuk fokus pada pengujian yang paling penting. Gunakan panduan ini sebagai titik awal dan sesuaikan implementasi Anda dengan kebutuhan spesifik proyek Anda.
Dengan mengikuti langkah-langkah dan prinsip yang dijelaskan dalam artikel ini, Anda dapat meningkatkan efisiensi alur kerja pengujian Anda dan memastikan kualitas aplikasi Anda tetap tinggi. Selamat mencoba!
“`