Membangun kepercayaan terhadap chart lewat testing berlapis: strategi unit/integration/E2E, helm test dengan test pods, helm-unittest dengan assertions dan snapshot, validasi manifest kubeconform & conftest, hingga otomasi penuh di CI dengan chart-testing (ct).

Setelah di episode 13 sebelumnya kita membahas schema validation — garis pertahanan pertama yang memastikan nilai yang masuk ke chart sudah benar tipe dan lengkap — pada episode kali ini kita membahas lapisan pertahanan berikutnya: testing chart. Kalau schema menjawab pertanyaan "apakah nilai yang diberikan valid?", testing menjawab pertanyaan yang lebih dalam: "apakah chart ini, dengan nilai yang valid, menghasilkan manifest yang benar dan berfungsi di cluster?"
Kenapa ini penting? Coba bayangkan kalian mempublikasikan chart ke tim yang tidak hanya satu — sepuluh tim di perusahaan memakai chart kalian, atau chart itu dipasang di ribuan cluster seperti chart populer di Artifact Hub. Setiap kali kalian mengubah template atau menambah key baru di values.yaml, ada ribuan instalasi yang berpotensi rusak. Tanpa testing, regresi tidak akan ketahuan sampai user melapor "release kami error setelah upgrade chart". Dengan testing otomatis yang berjalan setiap kali chart berubah, kesalahan seperti template yang tidak ter-render, indentasi YAML yang salah, atau key yang terhapus tanpa sengaja bisa ditangkap sebelum chart dipublikasikan.
Masalah yang dipecahkan di episode ini bukan sekadar "jalankan helm lint lalu selesai". Lint hanya memeriksa aturan statis. Kita butuh empat lapisan: unit testing untuk memastikan template me-render output yang benar dalam berbagai kondisi, integration testing untuk memastikan release benar-benar jalan di cluster, validasi manifest untuk memastikan output sesuai skema Kubernetes, dan otomasi CI agar semua lapisan itu berjalan otomatis di setiap perubahan. Mari kita bedah satu per satu.
Sebelum masuk ke tool, penting membangun mental model tentang empat jenis testing yang saling melengkapi:
Unit testing — menguji rendering template secara terisolasi: untuk satu set input values tertentu, apakah template me-render manifest yang diharapkan? Ini adalah lapisan tercepat, tidak butuh cluster, dan menangkap mayoritas bug chart (template typo, conditional yang salah, helper yang return nilai tak terduga). Tool-nya adalah plugin helm-unittest.
Integration testing — menginstall chart sungguhan ke cluster dan memverifikasi release benar-benar berfungsi: pod ready, service merespon, aplikasi bisa diakses. Tool-nya helm test dengan test pods yang mengeksekusi assertion di dalam cluster. Ini butuh cluster, lebih lambat, tapi memberikan jaminan paling nyata.
End-to-end testing — menjalankan skenario lengkap dari luar chart: deploy chart, lalu melakukan aksi nyata (misalnya request HTTP ke aplikasi dan mengecek respons). Ini sering digabung dengan integration testing dalam praktik nyata, di mana test pod melakukan request ke service.
Validation testing — memeriksa output rendering (manifest YAML) terhadap skema Kubernetes dan policy organisasi, tanpa cluster. Tool seperti kubeconform, kubeval, dan conftest membaca manifest yang dirender helm template lalu memvalidasinya terhadap skema API Kubernetes.
Keempat lapisan ini membentuk piramida: unit test banyak dan cepat di bawah, integration/E2E sedikit dan lambat di atas. Kalian tidak perlu semuanya untuk chart sederhana, tapi chart yang dipakai luas membutuhkan setidaknya unit testing + helm lint + validasi manifest, dan ditambah integration testing jika memungkinkan.
helm test — Memverifikasi Release di Dalam Clusterhelm test adalah fitur bawaan Helm untuk menjalankan test pods terhadap release yang sudah terinstall. Test pods pada dasarnya adalah pod khusus yang ditandai dengan annotation helm.sh/hook: test di dalam template chart. Ketika helm test <release> dijalankan, Helm membuat pod-pod tersebut, menjalankannya, dan menunggu status selesai.
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "mychart.fullname" . }}-test-connection"
labels:
{{- include "mychart.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget', '--spider', '--timeout=5', 'http://{{ include "mychart.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: NeverTest pod di atas melakukan permintaan HTTP spider (tanpa mengunduh body) ke Service aplikasi, memastikan service merespon. Logika intinya: exit code 0 berarti test lulus, non-zero berarti gagal. Karena itu command di dalam pod harus benar-benar mengecek kondisi yang diinginkan — bukan sekadar "jalan lalu selesai".
NAME READY STATUS ERRORS
myapp-test-connection 1/1 Completed 0Jika test gagal, Helm menampilkan error dan kalian bisa melihat log test pod untuk debug:
helm test my-release --logsFlag --logs (atau -l) mencetak log semua test pod — sangat berguna saat test gagal dan kalian perlu melihat mengapa. Perhatikan juga bahwa helm test hanya berfungsi pada release yang sudah terinstall (status deployed); menjalankannya pada release yang belum ada akan error. Dan karena test pods menggunakan annotation hook test, mereka tidak ikut dihitung sebagai bagian dari manifest normal release — helm get manifest tidak menampilkannya.
Note
Karena test pods menggunakan hook test, perilakunya mirip hook lain: pod dibuat saat helm test dipanggil dan dihapus setelah selesai sesuai hook-delete-policy (default: hook-succeeded). Setiap pemanggilan helm test membuat instance pod baru, sehingga test bersifat idempotent dan aman dijalankan berulang.
helm-unittestIntegration test dengan helm test butuh cluster dan lambat. Untuk iterasi cepat saat mengembangkan chart, kalian butuh unit test yang berjalan dalam milidetik tanpa cluster. Plugin helm-unittest menjawab kebutuhan ini: ia me-render template chart dengan values tertentu lalu membandingkan hasilnya dengan assertion.
Cara pakainya sederhana: install plugin, lalu tulis file test tests/*_test.yaml di dalam chart.
helm plugin install https://github.com/helm-unittest/helm-unittest.git
helm unittest mychartStruktur file test helm-unittest terdiri dari suite yang berisi beberapa set (skenario). Setiap set mendefinisikan values yang dipakai dan template yang diuji, diikuti assertion. Berikut contohnya:
suite: test deployment
templates:
- templates/deployment.yaml
tests:
- it: should render default replicas
set:
replicaCount: 3
asserts:
- isKind:
of: Deployment
- equal:
path: spec.replicas
value: 3Assertion di atas memeriksa dua hal: hasil render adalah resource berjenis Deployment, dan spec.replicas sama dengan 3 ketika replicaCount di-set ke 3. helm-unittest menyediakan puluhan assertion: equal, notEqual, exists, notExists, isKind, contains, matchRegex, isSubset, dan masih banyak lagi. Ada juga matchSnapshot untuk snapshot testing — mencocokkan output render dengan snapshot yang disimpan, sehingga perubahan tak terduga pada output langsung terdeteksi.
- it: should match snapshot
set:
image:
repository: nginx
tag: 1.27.0
asserts:
- matchSnapshot: {}Snapshot testing sangat berguna untuk menangkap regresi halus — misalnya perubahan indentasi YAML, key yang tiba-tiba hilang, atau format yang berubah — yang mungkin terlewat assertion spesifik. Ketika kalian sengaja mengubah output, update snapshot dengan flag --update-snapshot.
Tip
Kombinasikan helm-unittest dengan --with-subcharts untuk menguji chart beserta subcharts-nya, dan -f untuk memilih file test tertentu. Jalankan unit test di setiap perubahan template — ini lapisan paling cepat menangkap bug dan paling murah untuk dijalankan terus-menerus.
kubeconform, conftest, dan kube-scoreSetelah template me-render YAML, langkah berikutnya adalah memastikan outputnya sesuai dengan skema resource Kubernetes dan policy organisasi. Tiga tool berikut saling melengkapi.
kubeconform (penerus kubeval) memvalidasi manifest YAML terhadap skema OpenAPI resmi Kubernetes. Ia me-render chart dulu dengan helm template, lalu memeriksa setiap manifest. Ini menangkap masalah seperti field yang tidak dikenal di resource versi tertentu atau API version yang salah. Ini adalah "type checking" untuk manifest.
helm template my-release ./mychart | kubeconform -summarymyapp/templates/service.yaml - Service apps/v1beta1 Service.spec.ports: ...conftest memvalidasi manifest terhadap policy OPA (Open Policy Agent) yang ditulis dengan Rego. Berbeda dengan kubeconform yang memeriksa "apakah struktur valid", conftest memeriksa "apakah manifest sesuai kebijakan organisasi" — misalnya "image harus selalu pakai tag ter-pin, tidak boleh latest", "container wajib punya resource limits", atau "dilarang meng-expose privileged container". Ini adalah gerbang kepatuhan sebelum chart dipublikasikan.
helm template my-release ./mychart | conftest test --policy ./policyFAIL - myapp/templates/deployment.yaml - containers[0].image must not use 'latest' tagkube-score memberikan penilaian praktik terbaik keamanan dan keandalan: resource limits, liveness/readiness probe, securityContext, dan sejenisnya. Skornya memberi arah perbaikan tanpa bersifat absolut seperti policy.
Important
Untuk output yang stabil di pipeline, biasakan menambahkan --include-crds saat me-render chart yang punya CRD, dan perhatikan bahwa helm template me-render tanpa bergantung pada cluster. Ini membuat validasi manifest bisa berjalan penuh di CI tanpa akses cluster.
helm lint dan Best Practices Checkhelm lint adalah pemeriksa statis bawaan Helm yang memvalidasi struktur chart: apakah Chart.yaml valid, apakah file wajib ada, apakah ada masalah pada values.yaml dan template. Ia memeriksa sejumlah aturan — termasuk konvensi penamaan resource, keberadaan metadata, dan kesesuaian format. Ini adalah pemeriksaan paling dasar yang harus selalu lolos sebelum langkah apapun.
==> Linting ./mychart
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failedNamun, penting memahami batasannya: helm lint tidak me-render template dan tidak memvalidasi output terhadap skema Kubernetes. Ia bisa lolos padahal chart menghasilkan manifest yang invalid. Karena itu lint hanyalah lapisan paling dangkal — ia harus dipasangkan dengan unit test dan validasi manifest, bukan menggantikannya. Untuk aturan yang lebih ketat, kalian bisa menambah chart-testing (ct) yang akan kita bahas berikut, atau aturan kustom lewat linter external.
chart-testing (ct)Semua testing di atas akan kehilangan nilai jika tidak dijalankan otomatis. Di sinilah chart-testing (sering disebut ct) berperan: tool dari Helm community yang mengorkestrasi seluruh pipeline testing chart untuk CI. Ia biasanya dijalankan di GitHub Actions atau GitLab CI.
Fungsi utama ct:
ct mengidentifikasi chart mana yang berubah dibandingkan branch target, dan hanya men-test chart yang berubah. Ini menghindari membuang waktu men-test semua chart setiap kali.helm lint, helm template, dan helm install (ke cluster — seringnya kind atau k3s di CI) untuk chart yang berubah.Chart.yaml — mencegah publish chart dengan versi yang tidak berubah ke registry.Config ct ditulis dalam file YAML, biasanya ct.yaml di root repo chart:
remote: origin
target-branch: main
chart-dirs:
- charts
validate-maintainers: false
helm-extra-args: --timeout 600sContoh penggunaan di GitHub Actions — men-setup kind cluster, install ct, lalu jalankan lint dan install:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: helm/chart-testing-action@v2.6.1
- name: Run chart-testing (lint)
run: ct lint --config ct.yaml
- uses: helm/kind-action@v1.10.0
- name: Run chart-testing (install)
run: ct install --config ct.yamlct install adalah langkah yang paling berat: ia benar-benar menginstall chart ke cluster kind dan menjalankan helm test untuk setiap chart. Ini menggabungkan integration testing dengan pipeline CI. Untuk menjalankan test pod, pastikan chart-testing dijalankan dengan --all jika ingin men-test semua chart, atau biarkan default yang hanya men-test chart yang berubah pada PR.
Warning
ct install membutuhkan cluster Kubernetes yang berjalan di CI. Jalur paling umum adalah helm/kind-action (seperti di atas) atau runner k3s. Tanpa cluster, gunakan ct lint saja, dan jalankan helm template + kubeconform sebagai pengganti validasi yang tidak butuh cluster.
Mari kita rangkai semua lapisan ke dalam urutan yang masuk akal untuk chart production-grade. Alur ini bisa dijalankan lokal saat pengembangan, dan diulang otomatis di CI:
helm lint ./mychart
helm template my-release ./mychart --include-crds | kubeconform -summary
helm template my-release ./mychart | conftest test --policy ./policy
helm unittest ./mychart
helm install my-release ./mychart --wait --atomic
helm test my-releaseUrutan di atas membaca dari piramida: mulai dari yang murah dan cepat (lint, template+validasi, unit test) ke yang mahal dan lambat (install dan test di cluster). Jika salah satu lapisan awal gagal, pipeline berhenti lebih dulu — tidak ada gunanya menginstall ke cluster chart yang sudah gagal validasi.
Di CI, seluruh urutan ini dibungkus ct lint (untuk lint + template) dan ct install (untuk install + test), dengan checks versi otomatis. Hasilnya: setiap PR yang menyentuh chart memicu validasi lengkap, dan chart yang lolos baru bisa dipublikasikan.
Note
Mulailah sederhana: untuk chart internal, helm lint + helm-unittest + kubeconform sudah memberikan jaminan besar dengan biaya rendah. Tambahkan helm test dan ct install saat chart kalian mulai dipakai lintas tim atau dipublikasikan. Jangan biarkan kesempurnaan pipeline menghalangi kalian memulai — setiap lapisan yang aktif lebih baik daripada tidak ada.
Pada episode ini kita membahas cara membangun kepercayaan terhadap chart dengan testing berlapis: strategi empat lapis (unit, integration, E2E, dan validasi manifest); helm test yang memverifikasi release dengan test pods di dalam cluster; helm-unittest yang me-render dan memeriksa template secara cepat dengan assertion dan snapshot; validasi manifest dengan kubeconform, policy OPA dengan conftest, dan penilaian praktik terbaik dengan kube-score; helm lint sebagai pemeriksaan dasar; hingga otomasi penuh di CI menggunakan chart-testing (ct) yang mendeteksi chart berubah, me-lint, menginstall ke cluster, dan menjalankan test. Kombinasi dengan schema validation dari episode 13 membuat chart kalian aman dari kesalahan nilai dan kesalahan output.
Di episode 15 selanjutnya kita akan membahas dokumentasi chart — README.md yang menjadi kontrak antar tim, NOTES.txt yang memandu pengguna setelah instalasi, dokumentasi values yang rapi, dan otomasi dengan helm-docs. Chart yang teruji tanpa dokumentasi ibarat kode yang berfungsi tapi tak terbaca siapa pun — keduanya dibutuhkan agar chart kalian benar-benar dipakai. Pastikan tetap semangat!