

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Guía de pruebas de complementos
<a name="sbomgen-plugin-testing-guide"></a>

 Los autores de complementos escriben y prueban los complementos de Lua completamente en Lua, sin necesidad de usar la cadena de herramientas Go. Las pruebas se ubican junto con el complemento `init_test.lua` y se ejecutan mediante el comando. `inspector-sbomgen plugin test` 

 Para obtener información general sobre la creación de complementos, consulte la. [Guía para desarrolladores de complementos](sbomgen-plugin-developer-guide.md) Para ver el catálogo completo de funciones (incluida la `testing.*` API), consulta la[Referencia de la API de complementos](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 (Inicio rápido)
<a name="sbomgen-plugin-testing-guide-quick-start"></a>

### 1. Cree un archivo de prueba
<a name="sbomgen-plugin-testing-guide-1-create-a-test-file"></a>

 `init_test.lua`Colócalo junto al de tu plugin`init.lua`: 

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

### 2. Escribe funciones de prueba
<a name="sbomgen-plugin-testing-guide-2-write-test-functions"></a>

 `test_`Se descubre y ejecuta cualquier función global que comience por: 

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

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

## Diseño del directorio
<a name="sbomgen-plugin-testing-guide-directory-layout"></a>

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

 Los archivos de prueba y los datos de prueba se ubican en el mismo lugar que el complemento: 

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

### Nombre de los archivos de prueba
<a name="sbomgen-plugin-testing-guide-test-file-naming"></a>
+ Predeterminado: al `init_test.lua` lado del plugin `init.lua`
+ Varios archivos de prueba por plugin: `*_test.lua` se descubre cualquier archivo que coincida
+ Ejemplos: `init_test.lua`, `parsing_test.lua` y `discovery_test.lua`

### Datos de prueba: `_testdata/`
<a name="sbomgen-plugin-testing-guide-test-data-testdata"></a>

 Los datos de prueba se `_testdata/` encuentran junto al complemento. El subrayado inicial es una convención que mantiene los dispositivos separados visualmente de la fuente del complemento; el `plugin test` comando no se utiliza `_testdata/` cuando se buscan `*_test.lua` archivos, por lo que los dispositivos nunca se confunden con los archivos de prueba. 

 Los archivos de prueba hacen referencia a dispositivos con rutas relativas: 

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

 Las rutas se resuelven en relación con el directorio que contiene el archivo de prueba. 

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

### Funciones de escaneo
<a name="sbomgen-plugin-testing-guide-scan-functions"></a>

 Cada función de escaneo crea un artefacto, ejecuta el proceso de descubrimiento → recolección del complemento y devuelve los hallazgos. El autor de la prueba nunca crea artefactos, buses de eventos o registros manualmente. 

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

 Cada función de escaneo: 
+ Crea un artefacto nuevo para cada llamada (sin pérdidas de estado entre llamadas)
+ Carga solo el par Discovery \+ Collection del plugin actual
+ Devuelve una tabla de resultados

### Tabla de resultados
<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)
```

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

 La `sbomgen.*` API completa (E/S de archivos, expresiones regulares, información del sistema, registro, etc.) está disponible en los archivos de prueba, al igual que en los complementos de producción. Sin embargo, `sbomgen.*` las funciones que requieren un artefacto (por ejemplo`sbomgen.read_file()`) solo funcionan dentro de una `testing.scan_*` devolución de llamada; no están disponibles en el nivel superior de una función de prueba. 

## Ejecución de pruebas
<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
```

 La `--path` bandera acepta un directorio raíz de complementos (que contiene `discovery/` and/or `collection/`) o un directorio de ecosistema único (detectado automáticamente). El comando se cierra con un valor distinto de cero si alguna prueba falla. 

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

 Con`-v`, cada prueba imprime una `=== RUN` línea y una línea de resultado (`--- PASS``--- FAIL`, o`--- SKIP`). Sin ellas`-v`, solo se imprimen las pruebas fallidas. Al final se imprime una línea de resumen: 

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

## Probando los ayudantes de complementos
<a name="sbomgen-plugin-testing-guide-testing-plugin-helpers"></a>

 El archivo de prueba se carga en la misma máquina virtual de Lua que el plugin. `init.lua` Las funciones globales definidas en el complemento se pueden invocar desde las pruebas. Para probar las funciones auxiliares, expóngalas como globales o en una tabla de módulos: 

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

 Las funciones declaradas `local` en no `init.lua` están visibles en el archivo de prueba. Este es el alcance estándar de Lua. 

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

### VM compartida, estado compartido
<a name="sbomgen-plugin-testing-guide-shared-vm-shared-state"></a>

 Las funciones de prueba dentro de un único archivo comparten una máquina virtual Lua. Una variable global establecida en una `test_*` función es visible para las funciones subsiguientes. Si dos funciones definen la misma global, la segunda sobrescribe a la primera. Cada prueba debe ser independiente y no depender del estado de otras pruebas. 

### Orden de ejecución no determinista
<a name="sbomgen-plugin-testing-guide-non-deterministic-execution-order"></a>

 Las funciones de prueba se descubren iterando la tabla global de Lua, que utiliza un orden basado en hash. **No se garantiza que las pruebas se ejecuten en el orden en que están definidas.** No escriba pruebas que dependan del orden de ejecución. 

### Artefacto nuevo por llamada de escaneo
<a name="sbomgen-plugin-testing-guide-fresh-artifact-per-scan-call"></a>

 Cada llamada a `testing.scan_directory()` (o cualquier función de escaneo) crea un artefacto completamente nuevo. No se transmite ningún estado entre las llamadas de escaneo dentro de una prueba o entre las pruebas. 

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

 Los complementos se cargan una vez por ejecución de prueba, no una vez por archivo de prueba. El ejecutor de pruebas carga todos los complementos del sistema de archivos proporcionado y, a continuación, hace coincidir cada archivo de prueba con la máquina virtual del complemento correspondiente por fase, plataforma, categoría y ecosistema. 

### Comportamiento de las aserciones
<a name="sbomgen-plugin-testing-guide-assertion-behavior"></a>

 Cuando una aserción falla, se registra el error, pero la función de prueba continúa ejecutándose; las aserciones y sentencias subsiguientes se siguen ejecutando. Si más de una afirmación falla en la misma prueba, el error **más reciente** es el mensaje indicado en el resumen; los errores anteriores se sobrescriben. Para detener una prueba cuando se produce el primer error, regresa de la función después de la afirmación fallida (o utilízala `testing.fail()` dentro de una condicional). 

## Limitaciones
<a name="sbomgen-plugin-testing-guide-limitations"></a>
+ **`local`las funciones no se pueden comprobar.** Solo las funciones globales de `init.lua` son visibles en el archivo de prueba. Exponga a los ayudantes a través de una tabla de módulos si necesitan probarlos.
+ **No hay ningún `sbomgen.*` archivo I/O fuera de las llamadas de escaneo.** Funciones como estas `sbomgen.read_file()` requieren un contexto de artefacto, que solo existe dentro de `testing.scan_*` las llamadas.
+ **Sin ganchos durante el ciclo de vida.** No hay`before_each`, `after_each``setup`, o`teardown`. Cada función de prueba gestiona su propio estado.
+ **No hay tiempo de espera de la prueba.** Una función de prueba que se repite indefinidamente bloqueará el corredor.
+ **No hay informes de cobertura.** No hay forma de medir qué líneas `init.lua` se ejercieron.
+ **No hay puntos de referencia.** El marco de pruebas no admite los puntos de referencia de rendimiento.

## Responsabilidades del desarrollador
<a name="sbomgen-plugin-testing-guide-developer-responsibilities"></a>

### Al escribir un nuevo complemento de Lua
<a name="sbomgen-plugin-testing-guide-when-writing-a-new-lua-plugin"></a>
+ Crea `init_test.lua` junto a tu `init.lua`
+ Crea `_testdata/` con accesorios mínimos que ejerciten la lógica de tu complemento
+ Escribe `test_*` funciones que abarquen: la detección correcta, la extracción de versiones, los casos extremos y los escenarios de no coincidencia
+ Ejecute las pruebas localmente antes de enviarlas

### Directrices sobre los datos de las pruebas
<a name="sbomgen-plugin-testing-guide-test-data-guidelines"></a>
+ Mantenga los dispositivos al mínimo: utilice el archivo más pequeño que ejercite el comportamiento
+ Evite almacenar archivos binarios grandes `_testdata/` cuando bastaría con un pequeño elemento de texto
+ Cada complemento `_testdata/` debe ser independiente, sin referencias a archivos fuera del directorio de complementos