본문으로 건너뛰기

테스트

Greph은 세 단계의 테스트로 검증합니다.

  1. 단위 테스트: 파서, 워커, 코덱, 옵션 등 개별 구성 요소를 테스트합니다.
  2. 오라클 회귀 테스트 코퍼스: 고정된 시나리오 세트에서 Greph의 출력을 표준 grep, ripgrep 및 ast-grep 바이너리의 출력과 비교합니다.
  3. 프로브 기반 기능 매트릭스: rg 및 sg 래퍼에서 검증된 기능 범위를 확인합니다.

CI는 main에 푸시할 때마다, 그리고 모든 풀 리퀘스트(.github/workflows/ci.yml)에서 실행됩니다. 코딩 표준(composer cs), 정적 분석(composer analyse), PHPUnit 단위 및 통합 테스트 모음(composer test), 그리고 PHP 8.4에서 composer audit을 실행합니다. 오라클 코퍼스(composer test:oracle)는 CI에 포함되지 않으며, 기능 매트릭스는 php bin/feature-matrix로 수동 재생성합니다. PHPUnit 테스트 모음에는 업스트림 rg 및 sg을 사용할 수 없는 것으로 표시한 상태에서 매트릭스를 생성하고 보고서의 형식을 확인하는 테스트가 포함되어 있으므로, 프로브 하나가 회귀해도 실패하지 않습니다.

클론에서 작업하기

이 페이지의 모든 작업에는 저장소 클론이 필요합니다. 0.2.3 Composer 패키지에는 src/ 및 네 가지 런타임 실행 파일만 포함되므로, tests/, scenarios/, benchmarks/ 및 bin/의 개발 스크립트는 패키지에서 제외됩니다.

셸
git clone https://github.com/inline0/greph
cd greph
composer install

테스트 실행하기

셸
# PHPUnit unit and integration suites
composer test

# Oracle regression corpus
composer test:oracle

# Static analysis
composer analyse

# Coding standards
composer cs
composer cs:fix

# Full release-grade verification (analyse + cs + test + test:oracle)
composer verify

모든 릴리스는 composer verify을 통과해야 합니다. 통과하지 못하면 변경 작업은 완료된 것이 아닙니다.

오라클 모델

Greph은 오라클 기반 검증 모델을 따릅니다. 각 시나리오에서 세 가지 명령을 실행합니다.

  1. 오라클: 시나리오 코퍼스를 기준으로 캡처한 grep, ripgrep 또는 ast-grep입니다.
  2. 실제 결과: 동일한 코퍼스를 기준으로 캡처한 Greph입니다.
  3. 비교기: 줄 단위 또는 의미상 동일성을 확인하는 구조화된 비교입니다.

Greph이 오라클과 일치하지 않으면 Greph이 잘못된 것입니다. grep와 rg이 서로 일치하지 않으면 시나리오는 oracle_disagreement에 불일치를 기록하고, greph_follows에서 Greph이 따르는 도구를 명시하며, 다른 도구와의 비교를 skip로 설정합니다. 코퍼스에는 두 방향의 경우가 모두 있습니다.

텍스트 시나리오는 grep 및 rg과 비교하고, AST 및 재작성 시나리오는 sg와 비교합니다. 오라클 출력은 한 번 캡처해 각 시나리오의 oracle/ 디렉터리에 커밋하므로, 일반 실행에는 PHP만 필요합니다. 외부 도구는 오라클 출력을 캡처하거나 새로 고칠 때만 필요합니다.

구현은 tests/Oracle/에 있고 시나리오는 scenarios/text/, scenarios/ast/, scenarios/rewrite/ 및 scenarios/edge/에 있습니다.

시나리오 구성

각 시나리오는 독립된 디렉터리입니다.

코드
scenarios/text/literal-simple/
├── scenario.json     # name, category, pattern, flags, path
├── setup/            # corpus to search through
├── oracle/           # captured oracle output (grep.txt, rg.txt, rg.json, ...)
├── actual/           # captured greph output (generated, git-ignored)
└── reports/          # comparison results (generated, git-ignored)

scenario.json에는 패턴, 플래그 및 검색 경로를 선언합니다. 선택적 expectations 객체는 오라클(exact, semantic 또는 skip)별 비교 모드를 설정합니다. 이 객체가 없으면 텍스트 시나리오는 grep 및 rg을 정확히 비교하고 rg JSON은 의미상 비교하며, AST 및 재작성 시나리오는 sg와 비교합니다.

단일 시나리오 실행하기

저장소에는 개별 시나리오를 다루기 위한 소규모 CLI 모음이 있습니다. 이는 런타임 진입점이 아니라 개발 도구입니다. bin/의 런타임 바이너리와 함께 있지만 Composer 패키지에는 포함되지 않습니다. 각 도구에는 scenarios/ 기준 상대 경로로 시나리오 이름을 지정합니다.

셸
# Capture oracle output for a scenario (needs grep and rg, or sg)
./bin/oracle text/literal-simple

# Run greph against a scenario, capture its output
./bin/actual text/literal-simple

# Diff oracle vs actual
./bin/compare text/literal-simple

# Full pipeline: oracle (only if missing) -> actual -> compare
./bin/test-scenario text/literal-simple

# Recapture the oracle output first
./bin/test-scenario text/literal-simple --refresh

전체 회귀 테스트 모음 실행하기

셸
# All scenarios (the same as composer test:oracle)
./bin/test-regression

# Filter by category
./bin/test-regression --category text
./bin/test-regression --category ast
./bin/test-regression --category rewrite
./bin/test-regression --category edge

# Print only failures and the summary
./bin/test-regression --fast

# Recapture every oracle before comparing
./bin/test-regression --refresh

시나리오는 항상 한 번에 하나씩 실행됩니다. --jobs N은 허용되며 요약 행에 표시되지만, 병렬로 실행되는 작업은 없습니다(#7). 새로 클론한 저장소에서는 text/no-ignore 및 text/explicit-file-input가 실패합니다. setup/vendor/에 있는 픽스처 파일이 커밋되지 않았기 때문입니다(#6).

회귀 테스트 모음은 새로운 동작을 추가할 때 통과해야 하는 기준입니다. 새 플래그, 새 예외 사례 또는 새 버그 수정에는 오라클을 기준으로 기대 동작을 기록한 시나리오가 필요합니다.

규정 준수 보고

셸
./bin/verify-compliance

verify-compliance은 자체적으로 어떤 작업도 실행하지 않습니다. 마지막 시나리오 실행에서 남긴 오라클, 실제 결과 및 보고서 파일을 읽어 통과한 시나리오, 실패한 시나리오, 아직 보고서가 없는 시나리오를 출력합니다. 먼저 ./bin/test-regression을 실행하세요. --output report.json는 보고서를 JSON로도 작성합니다. 현재 브랜치가 릴리스할 준비가 되었는지 확인하려면 이 명령을 실행하세요.

테스트 주도 개발 워크플로우

기능을 추가할 때:

  1. 새 동작을 실행하는 코퍼스와 플래그를 포함한 시나리오 디렉터리를 작성합니다.
  2. ./bin/oracle <scenario>을 실행해 표준 도구의 출력을 캡처합니다.
  3. src/에서 기능을 구현합니다.
  4. ./bin/test-scenario <scenario>를 실행해 Greph가 오라클과 일치하는지 확인합니다.
  5. ./bin/test-regression --fast를 실행해 다른 부분에 회귀가 없는지 확인합니다.
  6. 커밋하기 전에 composer verify를 실행합니다.

버그를 수정할 때:

  1. 실패하는 입력을 시나리오로 캡처합니다.
  2. 오라클이 예상 출력을 생성하는지 확인합니다.
  3. Greph이 예상 출력을 생성하지 않는지 확인합니다.
  4. 버그를 수정합니다.
  5. Greph이 이제 오라클과 일치하는지 확인합니다.
  6. composer verify를 실행합니다.

시나리오는 코퍼스에 영구히 남으므로 composer test:oracle(및 composer verify)이 실패하지 않는 한 버그가 다시 발생할 수 없습니다.