

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 플러그인 테스트 가이드
<a name="sbomgen-plugin-testing-guide"></a>

 플러그인 작성자는 Lua 플러그인을 완전히 Lua로 작성하고 테스트합니다. Go 도구 체인은 필요하지 않습니다. 테스트는 아래의 플러그인과 함께 배치`init_test.lua`되며 `inspector-sbomgen plugin test` 명령을 통해 실행됩니다.

 일반적인 플러그인 작성은 단원을 참조하십시오[플러그인 개발자 안내서](sbomgen-plugin-developer-guide.md). 전체 함수 카탈로그(`testing.*`API 포함)는 단원을 참조하십시오[플러그인 API 참조](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
```

## 빠른 시작
<a name="sbomgen-plugin-testing-guide-quick-start"></a>

### 1. 테스트 파일 생성
<a name="sbomgen-plugin-testing-guide-1-create-a-test-file"></a>

 `init_test.lua` 플러그인의 옆에를 배치합니다`init.lua`.

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

### 2. 테스트 함수 쓰기
<a name="sbomgen-plugin-testing-guide-2-write-test-functions"></a>

 로 시작하는 모든 전역 함수`test_`가 검색되고 실행됩니다.

```
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. 테스트 실행
<a name="sbomgen-plugin-testing-guide-3-run-tests"></a>

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

## 디렉터리 레이아웃
<a name="sbomgen-plugin-testing-guide-directory-layout"></a>

### 플러그인 구조
<a name="sbomgen-plugin-testing-guide-plugin-structure"></a>

 테스트 파일 및 테스트 데이터는 플러그인과 함께 배치됩니다.

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

### 테스트 파일 이름 지정
<a name="sbomgen-plugin-testing-guide-test-file-naming"></a>
+ 기본값: 플러그인의 `init_test.lua`옆 `init.lua`
+ 플러그인당 여러 테스트 파일: 모든 파일 일치 `*_test.lua` 검색
+ 예: `init_test.lua`, `parsing_test.lua`, `discovery_test.lua` 

### 테스트 데이터: `_testdata/`
<a name="sbomgen-plugin-testing-guide-test-data-testdata"></a>

 플러그인 `_testdata/`옆의에 있는 데이터를 테스트합니다. 선행 밑줄은 픽스처를 플러그인 소스와 시각적으로 분리하는 규칙입니다. `*_test.lua` 파일을 검색할 `_testdata/` 때 `plugin test` 명령이 로 내려가지 않으므로 픽스처가 테스트 파일로 오인되지 않습니다.

 테스트 파일은 상대 경로가 있는 픽스처를 참조합니다.

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

 경로는 테스트 파일이 포함된 디렉터리를 기준으로 확인됩니다.

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

### 스캔 함수
<a name="sbomgen-plugin-testing-guide-scan-functions"></a>

 각 스캔 함수는 아티팩트를 생성하고, 플러그인의 검색 → 수집 파이프라인을 실행하고, 결과를 반환합니다. 테스트 작성자는 아티팩트, 이벤트 버스 또는 레지스트리를 수동으로 생성하지 않습니다.

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

 각 스캔 함수: 
+ 각 호출에 대해 새 아티팩트를 생성합니다( 호출 간에 상태 누수 없음).
+ 현재 플러그인의 검색 \+ 컬렉션 페어만 로드합니다.
+ 결과 테이블을 반환합니다.

### 결과 테이블
<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)
```

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

 전체 `sbomgen.*` API(파일 I/O, 정규식, 시스템 정보, 로깅 등)는 프로덕션 플러그인과 마찬가지로 테스트 파일에서 사용할 수 있습니다. 그러나 아티팩트(예: `sbomgen.read_file()`)가 필요한 `sbomgen.*` 함수는 `testing.scan_*` 콜백 내에서만 작동하며 테스트 함수의 최상위 수준에서는 사용할 수 없습니다.

## 테스트 실행
<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` 플래그는 플러그인 루트 디렉터리( `discovery/` 및/또는 포함`collection/`) 또는 단일 에코시스템 디렉터리(자동 감지됨)를 허용합니다. 테스트가 실패하면 0이 아닌 명령이 종료됩니다.

### 출력 형식
<a name="sbomgen-plugin-testing-guide-output-format"></a>

 를 사용하면 `-v`각 테스트가 `=== RUN` 줄과 결과 줄(`--- PASS`, `--- FAIL`또는 `--- SKIP`)을 인쇄합니다. 이 없으면 실패한 테스트`-v`만 인쇄됩니다. 요약 줄은 끝에 인쇄됩니다.

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

## 플러그인 헬퍼 테스트
<a name="sbomgen-plugin-testing-guide-testing-plugin-helpers"></a>

 테스트 파일은 플러그인의와 동일한 Lua VM에 로드됩니다`init.lua`. 플러그인에 정의된 전역 함수는 테스트에서 호출할 수 있습니다. 헬퍼 함수를 테스트하려면 글로벌 또는 모듈 테이블에 표시합니다.

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

 `local`에 선언된 함수`init.lua`는 테스트 파일에 표시되지 않습니다. 표준 Lua 범위 지정입니다.

## 동작 및 불변
<a name="sbomgen-plugin-testing-guide-behavior-and-invariants"></a>

### 공유 VM, 공유 상태
<a name="sbomgen-plugin-testing-guide-shared-vm-shared-state"></a>

 단일 파일 내의 테스트 함수는 Lua VM을 공유합니다. 한 `test_*` 함수에 설정된 전역 변수는 후속 함수에 표시됩니다. 두 함수가 동일한 전역을 정의하는 경우 두 번째 함수는 첫 번째 함수를 덮어씁니다. 각 테스트는 독립형이어야 하며 다른 테스트의 상태에 의존하지 않아야 합니다.

### 비결정적 실행 순서
<a name="sbomgen-plugin-testing-guide-non-deterministic-execution-order"></a>

 테스트 함수는 해시 기반 순서를 사용하는 Lua의 글로벌 테이블을 반복하여 검색됩니다. **테스트는 정의된 순서대로 실행되지 않습니다.** 실행 순서에 따라 달라지는 테스트를 작성하지 마십시오.

### 스캔 호출당 새로운 아티팩트
<a name="sbomgen-plugin-testing-guide-fresh-artifact-per-scan-call"></a>

 `testing.scan_directory()` (또는 스캔 함수)에 대한 각 호출은 완전히 새로운 아티팩트를 생성합니다. 테스트 내에서 또는 테스트 간에 스캔 호출 간에 전달되는 상태는 없습니다.

### 플러그인 로드
<a name="sbomgen-plugin-testing-guide-plugin-loading"></a>

 플러그인은 테스트 파일당 한 번이 아니라 테스트 실행당 한 번 로드됩니다. 테스트 실행기는 제공된 파일 시스템에서 모든 플러그인을 로드한 다음 각 테스트 파일을 단계, 플랫폼, 범주 및 에코시스템별로 해당 플러그인 VM에 일치시킵니다.

### 어설션 동작
<a name="sbomgen-plugin-testing-guide-assertion-behavior"></a>

 어설션이 실패하면 실패가 기록되지만 테스트 함수는 계속 실행되며 후속 어설션 및 문은 계속 실행됩니다. 동일한 테스트에서 둘 이상의 어설션이 실패하는 경우 **가장 최근** 실패는 요약에 보고된 메시지입니다. 이전 실패는 덮어씁니다. 첫 번째 실패 시 테스트를 중지하려면 실패한 어설션 후 함수에서를 반환합니다(또는 조건부 `testing.fail()` 내에서 사용).

## 제한 사항
<a name="sbomgen-plugin-testing-guide-limitations"></a>
+ **`local` 함수는 테스트할 수 없습니다.** 의 전역 함수만 테스트 파일에 `init.lua` 표시됩니다. 테스트가 필요한 경우 모듈 테이블을 통해 헬퍼를 노출합니다.
+ **스캔 호출 외부에 `sbomgen.*` 파일 I/O가 없습니다.** 와 같은 함수에는 `testing.scan_*` 호출 내에만 존재하는 아티팩트 컨텍스트가 `sbomgen.read_file()` 필요합니다.
+ **수명 주기 후크가 없습니다.** `before_each`, `setup`, 또는 `after_each`는 없습니다`teardown`. 각 테스트 함수는 자체 상태를 관리합니다.
+ **테스트 제한 시간이 없습니다.** 영구 반복되는 테스트 함수는 러너를 중단합니다.
+ **적용 범위 보고가 없습니다.** 어떤 줄을 연습`init.lua`했는지 측정할 수 있는 방법은 없습니다.
+ **벤치마크가 없습니다.** 테스트 프레임워크는 성능 벤치마크를 지원하지 않습니다.

## 개발자 책임
<a name="sbomgen-plugin-testing-guide-developer-responsibilities"></a>

### 새 Lua 플러그인을 작성할 때
<a name="sbomgen-plugin-testing-guide-when-writing-a-new-lua-plugin"></a>
+ `init_test.lua` 옆의 생성 `init.lua`
+ 플러그인 로직을 실행하는 최소 픽스처`_testdata/`로 생성
+ 성공적인 탐지, 버전 추출, 엣지 케이스 및 불일치 시나리오를 포함하는 쓰기 `test_*` 함수
+ 제출하기 전에 로컬에서 테스트 실행

### 테스트 데이터 지침
<a name="sbomgen-plugin-testing-guide-test-data-guidelines"></a>
+ 픽스처 최소화 - 동작을 수행하는 가장 작은 파일 사용
+ 작은 텍스트 픽스처로 충분할 `_testdata/` 때 큰 바이너리를에 커밋하지 마세요.
+ 각 플러그인은 독립형이어야 `_testdata/` 합니다. 플러그인 디렉터리 외부의 파일에 대한 참조가 없어야 합니다.