Test bukan bonus, melainkan jaring pengaman yang membuktikan skrip bekerja sebelum menyentuh produksi. Episode ini membahas Pester: struktur Describe, Context, dan It, assertion dengan Should, mocking, cakupan kode, hingga menjalankan test di pipeline CI/CD.

Di episode 23 kalian membuat skrip yang bisa menjelaskan dirinya sendiri — log, debugging, dan profiling. Tapi ada satu lompatan kepercayaan yang tersisa: skrip yang berjalan mulus di laptop kalian belum tentu benar di produksi. Bagaimana membuktikannya?
Inilah peran test. Test adalah pemeriksaan kualitas yang otomatis: bukan "saya rasa skrip ini bekerja", melainkan "saya punya 40 test yang membuktikannya, dan semuanya hijau". Seperti sebelum naik ke jalan raya, kalian tidak cukup berkata "saya bisa menyetir" — kalian lulus ujian praktik. Episode ini melengkapi skrip kalian dengan ujian praktik itu menggunakan Pester, framework testing de facto untuk PowerShell.
Pester adalah framework testing resmi komunitas PowerShell. Strukturnya sederhana dan konsisten: setiap test ditulis sebagai deskripsi perilaku dalam blok Describe yang berisi blok It sebagai pernyataan spesifik. Test yang ditulis dengan baik berfungsi ganda: spesifikasi sekaligus pembuktian.
Penting: Windows PowerShell 5.1 menyertakan Pester versi lama (3.4). Untuk fitur modern, pasang versi 5 terbaru:
Install-Module -Name Pester -Scope CurrentUser -Force
Import-Module Pester -MinimumVersion 5.0Install-Module mengambil Pester dari PowerShell Gallery. Tambahkan -Scope CurrentUser agar cukup terpasang untuk akun kalian — tanpa memerlukan admin.
Test Pester adalah skrip .Tests.ps1 yang diletakkan berdampingan dengan fungsi yang diuji. Kerangka dasarnya:
Describe "Fungsi Get-ServerUptime" {
Context "Saat server aktif" {
It "Mengembalikan durasi uptime" {
$result = Get-ServerUptime -ServerName "WEB-01"
$result | Should -Not -BeNullOrEmpty
}
}
}Tiga blok yang wajib kalian kuasai:
Describe — test suite: kelompok besar, biasanya satu per fungsi atau modul.Context — kondisi: pengelompokan test berdasarkan keadaan tertentu ("saat server aktif", "saat input kosong").It — satu kasus test: satu pernyataan spesifik yang bisa lolos atau gagal.Bacalah nama blok It sebagai kalimat utuh: "ketika server aktif, ia mengembalikan durasi uptime". Test yang terbaca seperti kalimat adalah dokumentasi hidup — orang lain membacanya seperti membaca spesifikasi, bukan kode.
Inti setiap test adalah assertion: pernyataan "saya percaya hasilnya begini". Di Pester, assertion ditulis dengan Should:
| Operator | Memeriksa | Contoh |
|---|---|---|
-Be | Kesetaraan nilai | Should -Be 42 |
-BeExactly | Kesetaraan huruf tepat | Should -BeExactly "OFFLINE" |
-BeGreaterThan | Lebih besar dari | Should -BeGreaterThan 0 |
-Contain | Keanggotaan koleksi | Should -Contain "WEB-01" |
-Throw | Error dilemparkan | Should -Throw |
-Not | Negasi | Should -Not -BeNullOrEmpty |
Contoh assertion pada fungsi konversi satuan:
Describe "Fungsi ConvertTo-Kilobyte" {
It "Mengubah 2048 byte menjadi 2 kilobyte" {
ConvertTo-Kilobyte -Bytes 2048 | Should -Be 2
}
It "Menolak nilai negatif" {
{ ConvertTo-Kilobyte -Bytes -1 } | Should -Throw
}
}Perhatikan baris kedua: blok skrip di dalam kurung kurawal diteruskan sebagai delegasi ke Should -Throw — Pester menjalankannya dan memastikan ia melempar error. Pola ini penting untuk menguji perilaku buruk, bukan hanya jalan yang mulus.
Tip
Pegang disiplin: satu It, satu hal yang diuji. Test yang memeriksa tiga hal sekaligus akan menyesatkan — ketika gagal, kalian tidak tahu bagian mana yang rusak. Test yang gagal di assertion pertama tidak pernah sampai ke assertion berikutnya, jadi memecah assertion berarti mendapatkan informasi diagnostik yang lebih tajam.
Test terbagi menjadi dua jenis besar:
Analogi bengkel: unit test adalah memeriksa mesin, rem, dan kaki-kaki satu per satu di meja kerja; integration test adalah menyalakan mobil di jalan. Keduanya perlu — kendaraan yang semua komponennya lolos inspeksi tetap bisa rusak saat dirakit.
Masalah unit test: bagaimana menguji fungsi yang memanggil cmdlet eksternal — misalnya Copy-Item yang menyalin file nyata? Memanggilnya di setiap test lambat, tidak deterministik, dan berbahaya. Solusinya mocking: mengganti perilaku cmdlet nyata dengan perilaku tiruan di dalam test.
Describe "Skrip Start-Backup" {
It "Berjalan tanpa menyentuh sistem file nyata" {
Mock Copy-Item { param($Source, $Destination) "Menyalin $Source" }
Mock Remove-Item { }
{ Start-Backup -Source "C:\Data" } | Should -Not -Throw
}
}Dengan Mock, test menjadi cepat, bisa dijalankan berkali-kali tanpa efek samping, dan tidak bergantung pada kondisi mesin. Perilaku nyata tetap diuji — oleh integration test terpisah yang dijalankan jarang, misalnya hanya di pipeline malam.
Coverage menjawab pertanyaan: dari seluruh baris kode, berapa persen yang benar-benar dieksekusi oleh test? Pester mengukurnya lewat parameter -CodeCoverage:
Invoke-Pester -Path ".\tests" -CodeCoverage ".\functions\*.ps1"Hasilnya menampilkan persentase baris yang teruji dan file mana yang belum tersentuh. Coverage adalah radar: area yang belum diuji terlihat jelas, sehingga kalian tahu di mana test berikutnya paling bernilai.
Important
Coverage tinggi bukan jaminan kebenaran. Test bisa menyentuh 100 persen baris kode tetapi tidak pernah memeriksa nilai yang benar — hanya memastikan tidak error. Anggap coverage sebagai alat penemu titik buta, bukan target angka. Fokus pada test yang bermakna: kondisi batas, input tidak valid, dan perilaku yang sudah pernah salah.
Untuk menjalankan seluruh test, gunakan Invoke-Pester:
Invoke-Pester -Path ".\tests"
Invoke-Pester -Path ".\tests" -Output Detailed
Invoke-Pester -Path ".\tests" -CI-Output Detailed menampilkan nama setiap It beserta hasilnya — paling berguna saat memburu kegagalan.-CI mengaktifkan mode ramah pipeline: output ringkas, tanpa warna dan tanpa karakter khusus, cocok untuk log CI.Untuk melaporkan hasil ke alat lain, ekspor dalam format NUnit XML yang dipahami hampir semua sistem CI:
$result = Invoke-Pester -Path ".\tests" -PassThru
$result | ConvertTo-NUnitXml -Path ".\TestResults.xml" -ErrorAction SilentlyContinueTest yang hanya dijalankan manual di laptop adalah test yang setengah mati — ia tidak pernah melindungi apa pun. Tujuan akhirnya: test berjalan otomatis di setiap commit, dan pipeline gagal jika ada test yang merah. Di GitHub Actions, satu langkah cukup:
- name: Jalankan test Pester
shell: pwsh
run: Invoke-Pester -Path "./tests" -CIDengan pola ini, setiap perubahan kode menghadapi gerbang: sebelum perubahan bisa digabung ke cabang utama, seluruh test harus lulus. Inilah jaring pengaman yang membuat tim berani merombak kode — karena kalian tahu apa pun yang rusak akan berteriak, bukan berbisik.
Di episode 24 ini kalian telah membangun fondasi pengujian: instalasi Pester dengan Install-Module; struktur test dengan Describe, Context, dan It yang terbaca seperti spesifikasi; assertion dengan Should dan operator -Be, -Contain, -Throw, -Not; perbedaan unit test dan integration test; mocking dependensi eksternal dengan Mock; pengukuran cakupan kode dengan -CodeCoverage; menjalankan dan mengekspor hasil dengan Invoke-Pester dan ConvertTo-NUnitXml; hingga integrasi ke pipeline CI/CD.
Poin kunci yang harus kalian bawa:
It, satu hal yang diuji; nama test terbaca seperti kalimat.Skrip kalian kini bisa membuktikan dirinya sendiri. Tapi test dan skrip itu sendiri masih bisa terhapus, ter-timpa, atau bertabrakan antar anggota tim. Di episode 25 selanjutnya kita menjawab itu: PowerShell & Git — menaruh skrip di bawah kontrol versi, kolaborasi lewat branching, otomatisasi test di pipeline, hingga menerbitkan modul ke PowerShell Gallery. Sampai jumpa!