

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Panduan pengujian plugin
<a name="sbomgen-plugin-testing-guide"></a>

 Penulis plugin menulis dan menguji plugin Lua sepenuhnya di Lua - tidak diperlukan rantai alat Go. Pengujian ditempatkan bersama dengan plugin di bawah `init_test.lua` dan dijalankan melalui `inspector-sbomgen plugin test` perintah. 

 Untuk penulisan plugin umum, lihat. [Panduan pengembang plugin](sbomgen-plugin-developer-guide.md) Untuk katalog fungsi lengkap (termasuk `testing.*` API), lihat[Referensi API Plugin](sbomgen-plugin-api-reference.md). 

```
-- init_test.lua (next to init.lua)
function test_discovers_curl_version()
    local result = testing.scan_directory("_testdata/include/curl")
    testing.assert_equals(1, #result.findings)
    testing.assert_equals("libcurl", result.findings[1].name)
    testing.assert_equals("8.14.1", result.findings[1].version)
end
```

```
# Run every test under a plugin directory
inspector-sbomgen plugin test --path ./my-plugins

# Verbose output — show each test name and result
inspector-sbomgen plugin test --path ./my-plugins -v
```

## Mulai Cepat
<a name="sbomgen-plugin-testing-guide-quick-start"></a>

### 1. Buat file pengujian
<a name="sbomgen-plugin-testing-guide-1-create-a-test-file"></a>

 Tempatkan di `init_test.lua` sebelah plugin Anda`init.lua`: 

```
my-plugin/
├── discovery/cross-platform/extra-ecosystems/curl/
│   ├── init.lua
│   ├── init_test.lua
│   └── _testdata/
│       └── include/curl/curlver.h
```

### 2. Tulis fungsi uji
<a name="sbomgen-plugin-testing-guide-2-write-test-functions"></a>

 Setiap fungsi global yang dimulai dengan `test_` ditemukan dan dijalankan: 

```
function test_finds_libcurl()
    local result = testing.scan_directory("_testdata/include/curl")
    testing.assert_equals(1, #result.findings)
    testing.assert_equals("libcurl", result.findings[1].name)
end

function test_no_findings_for_empty_dir()
    local result = testing.scan_directory("_testdata/empty")
    testing.assert_equals(0, #result.findings)
end
```

### 3. Jalankan tes
<a name="sbomgen-plugin-testing-guide-3-run-tests"></a>

```
inspector-sbomgen plugin test --path ./my-plugin
```

## Tata Letak Direktori
<a name="sbomgen-plugin-testing-guide-directory-layout"></a>

### Struktur plugin
<a name="sbomgen-plugin-testing-guide-plugin-structure"></a>

 File uji dan data uji ditempatkan bersama dengan plugin: 

```
my-plugins/
├── discovery/
│   └── cross-platform/
│       └── extra-ecosystems/
│           └── curl/
│               ├── init.lua          # plugin source
│               ├── init_test.lua     # test file
│               └── _testdata/        # test fixtures
│                   ├── include/curl/curlver.h
│                   └── binaries/unix/curl
├── collection/
│   └── cross-platform/
│       └── extra-ecosystems/
│           └── curl-installation/
│               ├── init.lua
│               └── init_test.lua
```

### Uji penamaan file
<a name="sbomgen-plugin-testing-guide-test-file-naming"></a>
+ Default: di `init_test.lua` sebelah plugin `init.lua`
+ Beberapa file uji per plugin: pencocokan `*_test.lua` file apa pun ditemukan
+ Contoh:`init_test.lua`,`parsing_test.lua`, `discovery_test.lua`

### Data uji: `_testdata/`
<a name="sbomgen-plugin-testing-guide-test-data-testdata"></a>

 Data uji tinggal di `_testdata/` sebelah plugin. Garis bawah utama adalah konvensi yang membuat perlengkapan terpisah secara visual dari sumber plugin; `plugin test` perintah tidak turun ke `_testdata/` saat mencari `*_test.lua` file, sehingga perlengkapan tidak pernah disalahartikan sebagai file uji. 

 Perlengkapan referensi file uji dengan jalur relatif: 

```
local result = testing.scan_directory("_testdata/include/curl")
```

 Jalur diselesaikan relatif terhadap direktori yang berisi file uji. 

## `testing.*`API
<a name="sbomgen-plugin-testing-guide-the-testing-api"></a>

### Fungsi Pindai
<a name="sbomgen-plugin-testing-guide-scan-functions"></a>

 Setiap fungsi pemindaian membuat artefak, menjalankan pipeline discovery → collection plugin, dan mengembalikan temuan. Penulis pengujian tidak pernah secara manual membuat artefak, bus acara, atau pendaftar. 

```
-- Scan a directory of test fixtures (most common)
local result = testing.scan_directory("_testdata/curl")

-- Alias for scan_directory (archives use the same backend)
local result = testing.scan_archive("_testdata/app.tar.gz")

-- Scan as a localhost artifact
local result = testing.scan_localhost("_testdata/curl")

-- Scan a compiled binary
local result = testing.scan_binary("_testdata/binaries/curl")

-- Scan a mounted volume
local result = testing.scan_volume("_testdata/volume-root")

-- Scan a container image tarball
local result = testing.scan_container("_testdata/images/alpine.tar")
```

 Setiap fungsi pemindaian: 
+ Membuat artefak baru untuk setiap panggilan (tidak ada kebocoran status di antara panggilan)
+ Hanya memuat pasangan koleksi discovery \+ plugin saat ini
+ Mengembalikan tabel hasil

### Tabel Hasil
<a name="sbomgen-plugin-testing-guide-result-table"></a>

```
result.findings              -- array of finding tables
result.findings[1].name      -- package name (string)
result.findings[1].version   -- package version (string)
result.findings[1].purl      -- package URL (string)
result.findings[1].component_type -- component type (string)
result.findings[1].properties    -- table<string, string>
result.findings[1].children      -- array of nested finding tables (same shape)
```

### Pernyataan
<a name="sbomgen-plugin-testing-guide-assertions"></a>

```
-- Equality
testing.assert_equals(expected, actual, message?)
testing.assert_not_equals(expected, actual, message?)

-- Truthiness
testing.assert_true(value, message?)
testing.assert_false(value, message?)

-- Nil checks
testing.assert_nil(value, message?)
testing.assert_not_nil(value, message?)

-- String
testing.assert_contains(haystack, needle, message?)
testing.assert_matches(string, pattern, message?)

-- Tables
testing.assert_length(table, expected_length, message?)

-- Control flow
testing.fail(message)    -- immediately fail the current test
testing.skip(message)    -- skip the current test (not a failure)
```

### `sbomgen.*`API standar
<a name="sbomgen-plugin-testing-guide-standard-sbomgen-api"></a>

 `sbomgen.*`API lengkap (file I/O, regex, info sistem, logging, dll.) Tersedia dalam file pengujian, sama seperti di plugin produksi. Namun, `sbomgen.*` fungsi yang memerlukan artefak (misalnya,`sbomgen.read_file()`) hanya berfungsi di dalam `testing.scan_*` panggilan balik — fungsi tersebut tidak tersedia di tingkat atas fungsi pengujian. 

## Menjalankan Tes
<a name="sbomgen-plugin-testing-guide-running-tests"></a>

```
# Run all tests under a plugin directory
inspector-sbomgen plugin test --path ./my-plugins

# Filter by regex pattern
inspector-sbomgen plugin test --path ./my-plugins --run curl

# Verbose output (show each test name and result)
inspector-sbomgen plugin test --path ./my-plugins -v

# Stop on the first failing test
inspector-sbomgen plugin test --path ./my-plugins --fail-fast
```

 `--path`Bendera menerima direktori root plugin (berisi `discovery/` and/or `collection/`) atau direktori ekosistem tunggal (terdeteksi otomatis). Perintah keluar bukan nol jika ada tes yang gagal. 

### Format output
<a name="sbomgen-plugin-testing-guide-output-format"></a>

 Dengan`-v`, setiap tes mencetak `=== RUN` garis dan garis hasil (`--- PASS`,`--- FAIL`, atau`--- SKIP`). Tanpa`-v`, hanya tes yang gagal dicetak. Baris ringkasan dicetak di bagian akhir: 

```
=== RUN   curl/discovery/init_test/test_discovers_libcurl_header
--- PASS: curl/discovery/init_test/test_discovers_libcurl_header (0.04s)
=== RUN   curl/discovery/init_test/test_discovers_curl_binary_unix
--- PASS: curl/discovery/init_test/test_discovers_curl_binary_unix (0.04s)
=== RUN   curl/discovery/init_test/test_no_findings_for_unrelated_files
--- PASS: curl/discovery/init_test/test_no_findings_for_unrelated_files (0.04s)
ok    3 tests passed
```

## Pembantu Plugin Pengujian
<a name="sbomgen-plugin-testing-guide-testing-plugin-helpers"></a>

 File pengujian dimuat ke Lua VM yang sama dengan plugin. `init.lua` Fungsi global yang didefinisikan dalam plugin dapat dipanggil dari pengujian. Untuk menguji fungsi pembantu, paparkan mereka sebagai global atau dalam tabel modul: 

```
-- init.lua
M = {}
function M.parse_version(raw)
    return string.match(raw, "(%d+%.%d+%.%d+)")
end

function collect(file_path)
    local ver = M.parse_version(...)
    -- ...
end
```

```
-- init_test.lua
function test_parse_version_extracts_semver()
    testing.assert_equals("1.2.3", M.parse_version("curl/1.2.3"))
end

function test_parse_version_returns_nil_for_garbage()
    testing.assert_nil(M.parse_version("not-a-version"))
end
```

 Fungsi yang `local` `init.lua` dideklarasikan tidak terlihat oleh file uji. Ini adalah pelingkupan Lua standar. 

## Perilaku dan Invarian
<a name="sbomgen-plugin-testing-guide-behavior-and-invariants"></a>

### VM bersama, status bersama
<a name="sbomgen-plugin-testing-guide-shared-vm-shared-state"></a>

 Fungsi uji dalam satu file berbagi VM Lua. Variabel global yang ditetapkan dalam satu `test_*` fungsi terlihat oleh fungsi selanjutnya. Jika dua fungsi mendefinisikan global yang sama, yang kedua menimpa yang pertama. Setiap tes harus mandiri dan tidak bergantung pada keadaan dari tes lain. 

### Perintah eksekusi non-deterministik
<a name="sbomgen-plugin-testing-guide-non-deterministic-execution-order"></a>

 Fungsi pengujian ditemukan dengan mengulangi tabel global Lua, yang menggunakan pemesanan berbasis hash. **Pengujian tidak dijamin berjalan sesuai urutan yang ditentukan.** Jangan menulis tes yang bergantung pada perintah eksekusi. 

### Artefak segar per panggilan pemindaian
<a name="sbomgen-plugin-testing-guide-fresh-artifact-per-scan-call"></a>

 Setiap panggilan ke `testing.scan_directory()` (atau fungsi pemindaian apa pun) menciptakan artefak yang sama sekali baru. Tidak ada status yang dilakukan antara pemindaian panggilan dalam tes atau di seluruh tes. 

### Pemuatan plugin
<a name="sbomgen-plugin-testing-guide-plugin-loading"></a>

 Plugin dimuat sekali per uji coba, tidak sekali per file pengujian. Pelari uji memuat semua plugin dari sistem file yang disediakan, lalu mencocokkan setiap file pengujian dengan plugin VM yang sesuai berdasarkan fase, platform, kategori, dan ekosistem. 

### Perilaku penegasan
<a name="sbomgen-plugin-testing-guide-assertion-behavior"></a>

 Ketika pernyataan gagal, kegagalan dicatat tetapi fungsi pengujian terus mengeksekusi — pernyataan dan pernyataan berikutnya masih berjalan. Jika lebih dari satu pernyataan gagal dalam tes yang sama, kegagalan **terbaru** adalah pesan yang dilaporkan dalam ringkasan; kegagalan sebelumnya ditimpa. Untuk menghentikan pengujian pada kegagalan pertamanya, kembali dari fungsi setelah pernyataan gagal (atau gunakan `testing.fail()` di dalam kondisional). 

## Batasan
<a name="sbomgen-plugin-testing-guide-limitations"></a>
+ **`local`fungsi tidak dapat diuji.** Hanya fungsi global dari `init.lua` yang terlihat ke file pengujian. Paparkan pembantu melalui tabel modul jika mereka membutuhkan pengujian.
+ **Tidak ada `sbomgen.*` file I/O di luar panggilan pemindaian.** Fungsi seperti `sbomgen.read_file()` memerlukan konteks artefak, yang hanya ada di dalam `testing.scan_*` panggilan.
+ **Tidak ada kait siklus hidup.** Tidak ada`before_each`,`after_each`,`setup`, atau`teardown`. Setiap fungsi pengujian mengelola statusnya sendiri.
+ **Tidak ada batas waktu tes.** Fungsi pengujian yang loop selamanya akan menggantung pelari.
+ **Tidak ada pelaporan cakupan.** Tidak ada cara untuk mengukur garis mana `init.lua` yang dilakukan.
+ **Tidak ada tolok ukur.** Kerangka pengujian tidak mendukung tolok ukur kinerja.

## Tanggung Jawab Pengembang
<a name="sbomgen-plugin-testing-guide-developer-responsibilities"></a>

### Saat menulis plugin Lua baru
<a name="sbomgen-plugin-testing-guide-when-writing-a-new-lua-plugin"></a>
+ Buat `init_test.lua` di sebelah Anda `init.lua`
+ Buat `_testdata/` dengan perlengkapan minimal yang menggunakan logika plugin Anda
+ Menulis `test_*` fungsi yang mencakup: deteksi berhasil, ekstraksi versi, kasus tepi, dan skenario tanpa kecocokan
+ Jalankan pengujian secara lokal sebelum mengirimkan

### Pedoman data uji
<a name="sbomgen-plugin-testing-guide-test-data-guidelines"></a>
+ Pertahankan perlengkapan minimal - gunakan file terkecil yang menjalankan perilaku
+ Hindari melakukan binari besar `_testdata/` ketika perlengkapan teks kecil sudah cukup
+ Setiap plugin `_testdata/` harus mandiri - tidak ada referensi ke file di luar direktori plugin