기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
플러그인 테스트 가이드
플러그인 작성자는 Lua 플러그인을 완전히 Lua로 작성하고 테스트합니다. Go 도구 체인은 필요하지 않습니다. 테스트는 아래의 플러그인과 함께 배치init_test.lua되며 inspector-sbomgen plugin test 명령을 통해 실행됩니다.
일반적인 플러그인 작성은 단원을 참조하십시오플러그인 개발자 안내서. 전체 함수 카탈로그(testing.*API 포함)는 단원을 참조하십시오플러그인 API 참조.
-- 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
빠른 시작
1. 테스트 파일 생성
init_test.lua 플러그인의 옆에를 배치합니다init.lua.
my-plugin/ ├── discovery/cross-platform/extra-ecosystems/curl/ │ ├── init.lua │ ├── init_test.lua │ └── _testdata/ │ └── include/curl/curlver.h
2. 테스트 함수 쓰기
로 시작하는 모든 전역 함수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. 테스트 실행
inspector-sbomgen plugin test --path ./my-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
테스트 파일 이름 지정
-
기본값: 플러그인의
init_test.lua옆init.lua -
플러그인당 여러 테스트 파일: 모든 파일 일치
*_test.lua검색 -
예:
init_test.lua,parsing_test.lua,discovery_test.lua
테스트 데이터: _testdata/
플러그인 _testdata/옆의에 있는 데이터를 테스트합니다. 선행 밑줄은 픽스처를 플러그인 소스와 시각적으로 분리하는 규칙입니다. *_test.lua 파일을 검색할 _testdata/ 때 plugin test 명령이 로 내려가지 않으므로 픽스처가 테스트 파일로 오인되지 않습니다.
테스트 파일은 상대 경로가 있는 픽스처를 참조합니다.
local result = testing.scan_directory("_testdata/include/curl")
경로는 테스트 파일이 포함된 디렉터리를 기준으로 확인됩니다.
testing.* API
스캔 함수
각 스캔 함수는 아티팩트를 생성하고, 플러그인의 검색 → 수집 파이프라인을 실행하고, 결과를 반환합니다. 테스트 작성자는 아티팩트, 이벤트 버스 또는 레지스트리를 수동으로 생성하지 않습니다.
-- 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")
각 스캔 함수:
-
각 호출에 대해 새 아티팩트를 생성합니다( 호출 간에 상태 누수 없음).
-
현재 플러그인의 검색 + 컬렉션 페어만 로드합니다.
-
결과 테이블을 반환합니다.
결과 테이블
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)
어설션
-- 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
전체 sbomgen.* API(파일 I/O, 정규식, 시스템 정보, 로깅 등)는 프로덕션 플러그인과 마찬가지로 테스트 파일에서 사용할 수 있습니다. 그러나 아티팩트(예: sbomgen.read_file())가 필요한 sbomgen.* 함수는 testing.scan_* 콜백 내에서만 작동하며 테스트 함수의 최상위 수준에서는 사용할 수 없습니다.
테스트 실행
# 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이 아닌 명령이 종료됩니다.
출력 형식
를 사용하면 -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
플러그인 헬퍼 테스트
테스트 파일은 플러그인의와 동일한 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 범위 지정입니다.
동작 및 불변
공유 VM, 공유 상태
단일 파일 내의 테스트 함수는 Lua VM을 공유합니다. 한 test_* 함수에 설정된 전역 변수는 후속 함수에 표시됩니다. 두 함수가 동일한 전역을 정의하는 경우 두 번째 함수는 첫 번째 함수를 덮어씁니다. 각 테스트는 독립형이어야 하며 다른 테스트의 상태에 의존하지 않아야 합니다.
비결정적 실행 순서
테스트 함수는 해시 기반 순서를 사용하는 Lua의 글로벌 테이블을 반복하여 검색됩니다. 테스트는 정의된 순서대로 실행되지 않습니다. 실행 순서에 따라 달라지는 테스트를 작성하지 마십시오.
스캔 호출당 새로운 아티팩트
testing.scan_directory() (또는 스캔 함수)에 대한 각 호출은 완전히 새로운 아티팩트를 생성합니다. 테스트 내에서 또는 테스트 간에 스캔 호출 간에 전달되는 상태는 없습니다.
플러그인 로드
플러그인은 테스트 파일당 한 번이 아니라 테스트 실행당 한 번 로드됩니다. 테스트 실행기는 제공된 파일 시스템에서 모든 플러그인을 로드한 다음 각 테스트 파일을 단계, 플랫폼, 범주 및 에코시스템별로 해당 플러그인 VM에 일치시킵니다.
어설션 동작
어설션이 실패하면 실패가 기록되지만 테스트 함수는 계속 실행되며 후속 어설션 및 문은 계속 실행됩니다. 동일한 테스트에서 둘 이상의 어설션이 실패하는 경우 가장 최근 실패는 요약에 보고된 메시지입니다. 이전 실패는 덮어씁니다. 첫 번째 실패 시 테스트를 중지하려면 실패한 어설션 후 함수에서를 반환합니다(또는 조건부 testing.fail() 내에서 사용).
제한 사항
-
local함수는 테스트할 수 없습니다. 의 전역 함수만 테스트 파일에init.lua표시됩니다. 테스트가 필요한 경우 모듈 테이블을 통해 헬퍼를 노출합니다. -
스캔 호출 외부에
sbomgen.*파일 I/O가 없습니다. 와 같은 함수에는testing.scan_*호출 내에만 존재하는 아티팩트 컨텍스트가sbomgen.read_file()필요합니다. -
수명 주기 후크가 없습니다.
before_each,setup, 또는after_each는 없습니다teardown. 각 테스트 함수는 자체 상태를 관리합니다. -
테스트 제한 시간이 없습니다. 영구 반복되는 테스트 함수는 러너를 중단합니다.
-
적용 범위 보고가 없습니다. 어떤 줄을 연습
init.lua했는지 측정할 수 있는 방법은 없습니다. -
벤치마크가 없습니다. 테스트 프레임워크는 성능 벤치마크를 지원하지 않습니다.
개발자 책임
새 Lua 플러그인을 작성할 때
-
init_test.lua옆의 생성init.lua -
플러그인 로직을 실행하는 최소 픽스처
_testdata/로 생성 -
성공적인 탐지, 버전 추출, 엣지 케이스 및 불일치 시나리오를 포함하는 쓰기
test_*함수 -
제출하기 전에 로컬에서 테스트 실행
테스트 데이터 지침
-
픽스처 최소화 - 동작을 수행하는 가장 작은 파일 사용
-
작은 텍스트 픽스처로 충분할
_testdata/때 큰 바이너리를에 커밋하지 마세요. -
각 플러그인은 독립형이어야
_testdata/합니다. 플러그인 디렉터리 외부의 파일에 대한 참조가 없어야 합니다.