

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Guida al test dei plugin
<a name="sbomgen-plugin-testing-guide"></a>

 Gli autori dei plugin scrivono e testano i plugin Lua interamente in Lua, senza bisogno della toolchain Go. I test sono collocati insieme al plugin sotto `init_test.lua` ed eseguiti tramite il comando. `inspector-sbomgen plugin test` 

 Per la creazione generale dei plugin, consulta. [Guida per sviluppatori di plugin](sbomgen-plugin-developer-guide.md) Per il catalogo completo delle funzioni (inclusa l'`testing.*`API), consulta[Riferimento all'API del 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
```

## Quick Start
<a name="sbomgen-plugin-testing-guide-quick-start"></a>

### 1. Crea un file di test
<a name="sbomgen-plugin-testing-guide-1-create-a-test-file"></a>

 Posiziona `init_test.lua` accanto a quello del tuo plugin`init.lua`: 

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

### 2. Scrivi funzioni di test
<a name="sbomgen-plugin-testing-guide-2-write-test-functions"></a>

 Qualsiasi funzione globale che inizia con `test_` viene rilevata ed eseguita: 

```
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. Esegui test
<a name="sbomgen-plugin-testing-guide-3-run-tests"></a>

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

## Layout delle directory
<a name="sbomgen-plugin-testing-guide-directory-layout"></a>

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

 I file di test e i dati di test si trovano insieme al 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
```

### Denominazione dei file di test
<a name="sbomgen-plugin-testing-guide-test-file-naming"></a>
+ Predefinito: `init_test.lua` accanto al plugin `init.lua`
+ Più file di test per plugin: `*_test.lua` viene rilevata qualsiasi corrispondenza tra file
+ Esempi: `init_test.lua`, `parsing_test.lua`, `discovery_test.lua`

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

 I dati di test si `_testdata/` trovano accanto al plugin. La caratteristica principale è una convenzione che mantiene le fixture visivamente separate dalla sorgente del plugin; il `plugin test` comando non viene utilizzato `_testdata/` durante la ricerca di `*_test.lua` file, quindi le fixture non vengono mai scambiate per file di test. 

 I file di test fanno riferimento a dispositivi con percorsi relativi: 

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

 I percorsi vengono risolti in relazione alla directory contenente il file di test. 

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

### Funzioni di scansione
<a name="sbomgen-plugin-testing-guide-scan-functions"></a>

 Ogni funzione di scansione crea un artefatto, esegue la pipeline discovery → collection del plugin e restituisce i risultati. L'autore del test non crea mai manualmente artefatti, bus di eventi o registri. 

```
-- 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")
```

 Ogni funzione di scansione: 
+ Crea un nuovo artefatto per ogni chiamata (nessuna perdita di stato tra le chiamate)
+ Carica solo la coppia di raccolta discovery\+ del plugin corrente
+ Restituisce una tabella dei risultati

### Tabella dei risultati
<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)
```

### Asserzioni
<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 standard
<a name="sbomgen-plugin-testing-guide-standard-sbomgen-api"></a>

 L'`sbomgen.*`API completa (file I/O, regex, informazioni di sistema, registrazione, ecc.) è disponibile nei file di test, come nei plugin di produzione. Tuttavia, `sbomgen.*` le funzioni che richiedono un artefatto (ad esempio`sbomgen.read_file()`) funzionano solo all'interno di un `testing.scan_*` callback: non sono disponibili al livello superiore di una funzione di test. 

## Esecuzione di test.
<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
```

 Il `--path` flag accetta una directory principale del plug-in (contenente `discovery/` and/or `collection/`) o una singola directory dell'ecosistema (rilevata automaticamente). Il comando esce da un valore diverso da zero se un test fallisce. 

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

 Con`-v`, ogni test stampa una `=== RUN` riga e una riga di risultato (`--- PASS``--- FAIL`, o`--- SKIP`). Senza`-v`, vengono stampati solo i test non riusciti. Alla fine viene stampata una riga riassuntiva: 

```
=== 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
```

## Testare gli helper dei plugin
<a name="sbomgen-plugin-testing-guide-testing-plugin-helpers"></a>

 Il file di test viene caricato nella stessa macchina virtuale Lua del plugin. `init.lua` Le funzioni globali definite nel plugin sono richiamabili dai test. Per testare le funzioni di supporto, esponile come globali o in una tabella di moduli: 

```
-- 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
```

 Le funzioni dichiarate `local` in non `init.lua` sono visibili nel file di test. Questo è lo scoping Lua standard. 

## Comportamento e invarianti
<a name="sbomgen-plugin-testing-guide-behavior-and-invariants"></a>

### VM condivisa, stato condiviso
<a name="sbomgen-plugin-testing-guide-shared-vm-shared-state"></a>

 Le funzioni di test all'interno di un singolo file condividono una VM Lua. Una variabile globale impostata in una `test_*` funzione è visibile alle funzioni successive. Se due funzioni definiscono lo stesso globale, la seconda sovrascrive la prima. Ogni test deve essere autonomo e non dipendere dallo stato degli altri test. 

### Ordine di esecuzione non deterministico
<a name="sbomgen-plugin-testing-guide-non-deterministic-execution-order"></a>

 Le funzioni di test vengono scoperte iterando la tabella globale di Lua, che utilizza l'ordinamento basato su hash. **Non è garantito che i test vengano eseguiti nell'ordine in cui sono stati definiti.** Non scrivete test che dipendono dall'ordine di esecuzione. 

### Nuovi artefatti per ogni chiamata di scansione
<a name="sbomgen-plugin-testing-guide-fresh-artifact-per-scan-call"></a>

 Ogni chiamata a `testing.scan_directory()` (o qualsiasi funzione di scansione) crea un artefatto completamente nuovo. Non viene rilevato alcuno stato tra le chiamate di scansione all'interno di un test o tra i test. 

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

 I plugin vengono caricati una volta per esecuzione di test, non una volta per file di test. Il test runner carica tutti i plugin dal filesystem fornito, quindi abbina ogni file di test alla macchina virtuale del plug-in corrispondente per fase, piattaforma, categoria ed ecosistema. 

### Comportamento di asserzione
<a name="sbomgen-plugin-testing-guide-assertion-behavior"></a>

 Quando un'asserzione fallisce, l'errore viene registrato ma la funzione di test continua a essere eseguita e le asserzioni e le istruzioni successive continuano a essere eseguite. Se più di un'asserzione fallisce nello stesso test, l'errore **più recente** è il messaggio riportato nel riepilogo; gli errori precedenti vengono sovrascritti. Per interrompere un test al primo errore, tornate dalla funzione dopo l'asserzione fallita (o `testing.fail()` usatela all'interno di un condizionale). 

## Limitazioni
<a name="sbomgen-plugin-testing-guide-limitations"></a>
+ **`local`le funzioni non sono testabili.** Solo le funzioni globali di `init.lua` sono visibili nel file di test. Esponete gli helper tramite una tabella di moduli se hanno bisogno di essere testati.
+ **Nessun `sbomgen.*` file I/O al di fuori delle chiamate di scansione.** Funzioni come quelle `sbomgen.read_file()` richiedono un contesto di artefatti, che esiste solo all'interno `testing.scan_*` delle chiamate.
+ **Nessun aggancio al ciclo di vita.** Non c'è`before_each`,`after_each`, `setup` o. `teardown` Ogni funzione di test gestisce il proprio stato.
+ **Nessun timeout per il test.** Una funzione di test che si ripete per sempre bloccherà il runner.
+ **Nessuna segnalazione sulla copertura.** Non c'è modo di misurare quali linee `init.lua` sono state esercitate.
+ **Nessun benchmark.** Il framework di test non supporta i benchmark delle prestazioni.

## Responsabilità degli sviluppatori
<a name="sbomgen-plugin-testing-guide-developer-responsibilities"></a>

### Quando si scrive un nuovo plugin Lua
<a name="sbomgen-plugin-testing-guide-when-writing-a-new-lua-plugin"></a>
+ Crea `init_test.lua` accanto al tuo `init.lua`
+ Crea `_testdata/` con dispositivi minimi che esercitano la logica del tuo plugin
+ Scrivi `test_*` funzioni che coprono: rilevamento riuscito, estrazione della versione, casi limite e scenari senza corrispondenza
+ Esegui i test localmente prima di inviarli

### Linee guida sui dati dei test
<a name="sbomgen-plugin-testing-guide-test-data-guidelines"></a>
+ Riduci al minimo le apparecchiature: utilizza il file più piccolo che esercita il comportamento
+ Evita di inserire file binari di grandi dimensioni in `_testdata/` cui sarebbe sufficiente una piccola finestra di testo
+ Ogni plugin `_testdata/` dovrebbe essere autonomo, senza riferimenti a file al di fuori della directory dei plugin