

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Guia de teste de plug-ins
<a name="sbomgen-plugin-testing-guide"></a>

 Os autores de plug-ins escrevem e testam plug-ins Lua inteiramente em Lua, sem a necessidade de uma cadeia de ferramentas Go. Os testes são colocados junto com o plug-in abaixo `init_test.lua` e executados por meio do `inspector-sbomgen plugin test` comando. 

 Para a criação geral de plug-ins, consulte o. [Guia do desenvolvedor de plug-ins](sbomgen-plugin-developer-guide.md) Para ver o catálogo completo de funções (incluindo a `testing.*` API), consulte [Referência da API de plug-in](sbomgen-plugin-api-reference.md) o. 

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

## Início rápido
<a name="sbomgen-plugin-testing-guide-quick-start"></a>

### 1. Crie um arquivo de teste
<a name="sbomgen-plugin-testing-guide-1-create-a-test-file"></a>

 Coloque `init_test.lua` ao lado do seu plugin`init.lua`: 

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

### 2. Escreva funções de teste
<a name="sbomgen-plugin-testing-guide-2-write-test-functions"></a>

 Qualquer função global que comece com `test_` é descoberta e executada: 

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

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

## Layout do diretório
<a name="sbomgen-plugin-testing-guide-directory-layout"></a>

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

 Os arquivos de teste e os dados de teste são co-localizados com o plug-in: 

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

### Nomeação do arquivo de teste
<a name="sbomgen-plugin-testing-guide-test-file-naming"></a>
+ Padrão: ao `init_test.lua` lado do plugin `init.lua`
+ Vários arquivos de teste por plug-in: qualquer arquivo correspondente `*_test.lua` é descoberto
+ Exemplos: `init_test.lua`, `parsing_test.lua`, `discovery_test.lua`

### Dados do teste: `_testdata/`
<a name="sbomgen-plugin-testing-guide-test-data-testdata"></a>

 Os dados de teste estão `_testdata/` ao lado do plug-in. O sublinhado principal é uma convenção que mantém os acessórios visualmente separados da fonte do plug-in; o `plugin test` comando não aparece `_testdata/` ao pesquisar `*_test.lua` arquivos, portanto, os acessórios nunca são confundidos com arquivos de teste. 

 Arquivos de teste referenciam luminárias com caminhos relativos: 

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

 Os caminhos são resolvidos em relação ao diretório que contém o arquivo de teste. 

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

### Funções de digitalização
<a name="sbomgen-plugin-testing-guide-scan-functions"></a>

 Cada função de escaneamento cria um artefato, executa o pipeline de descoberta → coleta do plug-in e retorna as descobertas. O autor do teste nunca cria manualmente artefatos, barramentos de eventos ou registros. 

```
-- 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 função de digitalização: 
+ Cria um novo artefato para cada chamada (sem vazamentos de estado entre as chamadas)
+ Carrega somente o par de descoberta \+ coleção do plugin atual
+ Retorna uma tabela de resultados

### Tabela 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)
```

### Asserções
<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 padrão
<a name="sbomgen-plugin-testing-guide-standard-sbomgen-api"></a>

 A `sbomgen.*` API completa (E/S de arquivo, regex, informações do sistema, registro etc.) está disponível em arquivos de teste, assim como nos plug-ins de produção. No entanto, `sbomgen.*` funções que exigem um artefato (por exemplo,`sbomgen.read_file()`) só funcionam dentro de um `testing.scan_*` retorno de chamada — elas não estão disponíveis no nível superior de uma função de teste. 

## Execução de testes
<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
```

 O `--path` sinalizador aceita um diretório raiz do plug-in (contendo `discovery/` and/or `collection/`) ou um único diretório de ecossistema (detectado automaticamente). O comando sai de forma diferente de zero se algum teste falhar. 

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

 Com`-v`, cada teste imprime uma `=== RUN` linha e uma linha de resultado (`--- PASS`,`--- FAIL`, ou`--- SKIP`). Sem`-v`, apenas testes falhos são impressos. Uma linha de resumo é impressa no final: 

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

## Testando auxiliares de plug-ins
<a name="sbomgen-plugin-testing-guide-testing-plugin-helpers"></a>

 O arquivo de teste é carregado na mesma Lua VM que a do `init.lua` plug-in. As funções globais definidas no plug-in podem ser chamadas a partir de testes. Para testar funções auxiliares, exponha-as como globais ou em uma tabela 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
```

 As funções `init.lua` declaradas `local` em não são visíveis no arquivo de teste. Esse é o escopo padrão de Lua. 

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

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

 Funções de teste em um único arquivo compartilham uma Lua VM. Uma variável global definida em uma `test_*` função é visível para as funções subsequentes. Se duas funções definem o mesmo global, a segunda substitui a primeira. Cada teste deve ser independente e não depender do estado de outros testes. 

### Ordem de execução não determinística
<a name="sbomgen-plugin-testing-guide-non-deterministic-execution-order"></a>

 As funções de teste são descobertas pela iteração da tabela global de Lua, que usa ordenação baseada em hash. **Não é garantido que os testes sejam executados na ordem em que foram definidos.** Não escreva testes que dependam da ordem de execução. 

### Novo artefato por chamada de escaneamento
<a name="sbomgen-plugin-testing-guide-fresh-artifact-per-scan-call"></a>

 Cada chamada para `testing.scan_directory()` (ou qualquer função de escaneamento) cria um artefato completamente novo. Não há nenhum estado transmitido entre as chamadas de escaneamento em um teste ou entre os testes. 

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

 Os plug-ins são carregados uma vez por execução de teste, não uma vez por arquivo de teste. O executor de teste carrega todos os plug-ins do sistema de arquivos fornecido e, em seguida, combina cada arquivo de teste com a VM de plug-in correspondente por fase, plataforma, categoria e ecossistema. 

### Comportamento de afirmação
<a name="sbomgen-plugin-testing-guide-assertion-behavior"></a>

 Quando uma afirmação falha, a falha é registrada, mas a função de teste continua em execução — afirmações e instruções subsequentes ainda são executadas. Se mais de uma afirmação falhar no mesmo teste, a falha **mais recente** será a mensagem relatada no resumo; as falhas anteriores serão substituídas. Para interromper um teste em sua primeira falha, retorne da função após a afirmação com falha (ou use `testing.fail()` dentro de uma condicional). 

## Limitações
<a name="sbomgen-plugin-testing-guide-limitations"></a>
+ **`local`as funções não são testáveis.** Somente as funções globais de `init.lua` são visíveis no arquivo de teste. Exponha os ajudantes por meio de uma tabela de módulos se eles precisarem de testes.
+ **Nenhum `sbomgen.*` arquivo I/O fora das chamadas de escaneamento.** Funções como `sbomgen.read_file()` exigem um contexto de artefato, que só existe dentro das `testing.scan_*` chamadas.
+ **Sem ganchos para o ciclo de vida.** Não há`before_each`,`after_each`,`setup`, ou`teardown`. Cada função de teste gerencia seu próprio estado.
+ **Sem tempo limite de teste.** Uma função de teste que se repete eternamente suspenderá o corredor.
+ **Sem relatórios de cobertura.** Não há como medir quais linhas de `init.lua` foram exercidas.
+ **Sem benchmarks.** A estrutura de teste não oferece suporte a benchmarks de desempenho.

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

### Ao escrever um novo plugin Lua
<a name="sbomgen-plugin-testing-guide-when-writing-a-new-lua-plugin"></a>
+ Crie `init_test.lua` ao lado do seu `init.lua`
+ Crie `_testdata/` com o mínimo de acessórios que exercem a lógica do seu plugin
+ `test_*`Funções de gravação que abrangem: detecção bem-sucedida, extração de versões, casos extremos e cenários sem correspondência
+ Execute testes localmente antes de enviar

### Diretrizes de dados de teste
<a name="sbomgen-plugin-testing-guide-test-data-guidelines"></a>
+ Mantenha o mínimo de luminárias — use o menor arquivo que exercita o comportamento
+ Evite comprometer binários grandes `_testdata/` quando uma pequena configuração de texto seria suficiente
+ Cada plug-in `_testdata/` deve ser independente — sem referências a arquivos fora do diretório do plug-in