Skip to content

Satu Baris package clause yang Tetap Lolos Build, Vet, dan Test

Adityo Guni Waluyo

Klausa paket yang salah pada file uji Go tetap lolos go build, go vet, dan go test setelah relokasi. Mekanisme pengenal impor dan cara menjaganya.

Ringkasan

File uji yang pindah direktori masih pakai klausa package servicetype, bukan servicetype_test, tapi lolos go build, vet, dan test. Soalnya setelah pindah, larangan import cycle hilang, jadi impor senama jadi legal dan toolchain nggak protes. Moralnya: habis mindahin uji Go, cek baris pertama tiap file secara manual.

Satu baris package servicetype yang seharusnya servicetype_test.

Saat meninjau tugas relokasi uji ke tree terpusat di repo KotaPortal (alias), mata saya berhenti di baris pertama sebuah file integrasi yang baru pindah: klausa paketnya masih package servicetype, bukan package servicetype_test. Tugasnya memindahkan uji ke api/tests/integration/servicetype/, dan file itu lolos dari tangan saya di iterasi sebelumnya. Dugaan saya waktu itu: ini pasti ketahuan lebih dulu oleh toolchain. Klausa salah = paket salah, dan go build pasti berteriak sebelum saya sempat melihatnya.

Ternyata semua lampu hijau. go build keluar 0, go vet diam, go test sukses. Baris yang salah itu lolos dari tiga gerbang sekaligus, dan hanya berhenti karena review manusia.

Kenapa tetap compile

Kuncinya ada di cara Go mengikat nama. Spesifikasi bahasanya menulis: "If the PackageName is omitted, it defaults to the identifier specified in the package clause of the imported package" [1]. Artinya, impor import "…/servicetype" tanpa alias mendeklarasikan identifier bernama servicetype di file itu. Kalau klausa file masih package servicetype, semua referensi servicetype.X() dianggap memanggil impor itu. Secara sintaksis, tidak ada yang rusak.

Lalu kenapa boleh ada impor bernama sama dengan paket file itu sendiri? Karena aturan larangannya bukan soal nama, tapi soal bentuk: "It is illegal for a package to import itself, directly or indirectly" [1]. Di lokasi lama, file uji hidup di direktori paket servicetype, dan "Each package within a module is a collection of source files in the same directory that are compiled together" [3]. Identitas paket = direktori. Mengimpor paket sendiri dari dalam paket sendiri berarti siklus impor, dan compiler menolaknya. File itu tidak mungkin salah klausa diam-diam di tempat asalnya; ia bahkan tidak akan pernah compile dengan bentuk seperti itu.

Setelah pindah ke tests/integration/servicetype/, jalur paket file berubah [3], larangan siklus hilang, dan impor senama jadi legal. Relokasi mekanis mengubah aturan mana yang berlaku pada kode yang sama. Saya membuktikan polanya di modul kecil terpisah: file uji dengan klausa package svc plus impor senama, di direktori baru, lolos go build, go vet, dan go test; file yang sama di direktori asli gagal dengan "import cycle not allowed in test".

Gerbang yang memeriksa hal yang berbeda

Konvensi uji kotak-hitam menyatakan file dalam paket _test "must be imported explicitly and only its exported identifiers may be used" [2]. Catat kata kuncinya: paket yang diuji harus diimpor secara eksplisit, dan compiler memang menegakkan konsekuensinya. Dengan klausa servicetype_test, semua simbol internal langsung jadi tak terjangkau; satu referensi ke fungsi internal langsung merah. Itu penegakan tidak langsung: compiler memvalidasi keterjangkauan identifier, bukan teks klausa. Karena di commit ini semua simbol yang dipakai memang sudah terekspor, klausa yang salah tidak menyentuh penegakan itu, jadi tidak ada yang merah.

Pelajaran yang saya bawa: lampu hijau mengukur kode seperti tertulis, bukan hubungan paket yang dimaksud. go build/go vet/go test menjawab "apakah ini compile dan jalan", bukan "apakah file ini menguji paket dari luar sesuai niat". Niat arsitektural itu tidak punya gerbang otomatis di sini; penjaganya prosedural. Di commit perbaikannya, satu-satunya perubahan adalah membalik klausa jadi servicetype_test; tidak ada baris lain.

Ritual kecil setelah memindahkan uji

Sejak itu, checklist saya saat relokasi uji Go bertambah satu item: setelah semua hijau, buka diff dan lihat baris pertama tiap file yang pindah. Satu baris itu yang tidak bisa diandalkan pada toolchain. Kasus lain di commit yang sama menegaskan polanya: file handler uji yang hanya menyentuh primitif auth dipindah dan klausanya ikut diganti admin_test → auth_test, impor tak terpakai dilepas. Pindah tempat berarti ganti identitas, dan identitas itu tertulis di baris pertama.

Sumber

  1. The Go Programming Language Specification
  2. Package testing
  3. Go Modules Reference

Artikel terkait