Preskoči na vsebino

Testiranje

Greph je preverjen s tremi ravnmi testov:

  1. Enotski testi za izolirane komponente (razčlenjevalnike, sprehajalnike, kodeke, možnosti).
  2. Regresijski korpus referenčnih rezultatov, ki primerja izhod Greph s kanoničnimi binarnimi datotekami grep, ripgrep in ast-grep na določenem naboru scenarijev.
  3. Matrika funkcij na podlagi preverjanj, ki potrjuje preverjeni obseg ovojnika rg in sg.

CI se zažene ob vsakem potisku v main in ob vsakem zahtevku za spajanje (.github/workflows/ci.yml). Izvede preverjanje slogov kode (composer cs), statično analizo (composer analyse), enotske in integracijske zbirke PHPUnit (composer test) ter composer audit v PHP 8.4. Korpus referenčnih rezultatov (composer test:oracle) ni del CI, matrika funkcij pa se znova ustvari ročno z php bin/feature-matrix. Zbirka PHPUnit vsebuje test, ki ustvari matriko, pri čemer sta orodji iz zgornjega toka rg in sg označeni kot nedostopni, nato pa preveri obliko poročila, zato ne odpove, če se posamezno preverjanje poslabša.

Delo s klonom

Za vse na tej strani potrebujete klon repozitorija. Ker paket Composer za 0.2.3 vsebuje samo src/ in štiri izvedljive datoteke za izvajanje, tests/, scenarios/, benchmarks/ in razvojni skripti v bin/ niso vključeni vanj.

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

Zagon testov

Lupina
# 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 je pogoj za vsako izdajo. Če ne uspe, sprememba še ni dokončana.

Model referenčnih rezultatov

Greph uporablja model preverjanja na podlagi referenčnih rezultatov. Za vsak scenarij se zaženejo trije ukazi:

  1. Referenčni rezultat: grep, ripgrep ali ast-grep, zajet glede na korpus scenarijev.
  2. Dejanski rezultat: Greph, zajet glede na isti korpus.
  3. Primerjalnik: strukturirana primerjava, ki preveri enakovrednost po vrsticah ali semantično enakovrednost.

Če se Greph ne ujema z referenčnim rezultatom, je Greph napačen. Če se grep in rg ne ujemata, scenarij zabeleži neskladje pod oracle_disagreement, poimenuje orodje, ki mu Greph sledi v greph_follows, in primerjavo z drugim orodjem nastavi na skip. V korpusu sta zajeti obe smeri.

Besedilne scenarije primerjamo z grep in rg, scenarije AST in prepisovanja pa z sg. Izhod referenčnega orodja zajamemo enkrat in ga shranimo v imenik oracle/ posameznega scenarija, zato običajen zagon potrebuje samo PHP; zunanja orodja so potrebna le za zajem ali osvežitev referenčnega izhoda.

Implementacija je v tests/Oracle/, scenariji pa v scenarios/text/, scenarios/ast/, scenarios/rewrite/ in scenarios/edge/.

Postavitev scenarijev

Vsak scenarij je samostojen imenik:

Koda
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 določa vzorec, zastavice in iskalno pot. Izbirni objekt expectations nastavi način primerjave za vsak referenčni rezultat (exact, semantic ali skip); brez njega se besedilni scenariji natančno primerjajo za grep in rg, za rg JSON pa semantično, scenariji AST in prepisovanja pa se primerjajo z sg.

Zagon posameznega scenarija

Repozitorij vsebuje manjši nabor orodij CLI za delo s posameznimi scenariji. To so razvojna orodja, ne vstopne točke izvajalnega okolja: poleg binarnih datotek izvajalnega okolja so v bin/, vendar niso del paketa Composer. Vsako prejme ime scenarija glede na scenarios/.

Lupina
# 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

Zagon celotne regresijske zbirke

Lupina
# 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

Scenariji se vedno izvajajo eden za drugim. --jobs N je sprejet in izpisan v povzetku, vendar se nič ne izvede vzporedno (#7). V svežem klonu text/no-ignore in text/explicit-file-input ne uspeta, ker njune datoteke s testnimi podatki v setup/vendor/ niso vključene v repozitorij (#6).

Regresijska zbirka je pogoj za uvedbo novega vedenja. Nova zastavica, robni primer ali odprava napake zahtevajo scenarij, ki zajame pričakovano vedenje glede na referenčno orodje.

Poročanje o skladnosti

Lupina
./bin/verify-compliance

verify-compliance sam ne izvede ničesar. Prebere datoteke z referenčnimi rezultati, dejanskimi rezultati in poročili, ki so jih pustili zadnji zagnani scenariji, ter izpiše, kateri scenariji so uspešni, kateri neuspešni in za katere še ni poročila. Najprej zaženite ./bin/test-regression. --output report.json prav tako zapiše poročilo kot JSON. To je pravi ukaz, kadar želite vedeti, ali je trenutna veja pripravljena za izdajo.

Potek razvoja na podlagi testov

Pri dodajanju funkcije:

  1. Zapišite imenik scenarija s korpusom in zastavicami, ki preizkusijo novo vedenje.
  2. Zaženite ./bin/oracle <scenario>, da zajamete izhod kanoničnega orodja.
  3. Implementirajte funkcijo v src/.
  4. Zaženite ./bin/test-scenario <scenario> in preverite, ali se Greph ujema z referenčnim rezultatom.
  5. Zaženite ./bin/test-regression --fast in se prepričajte, da se nič drugega ni poslabšalo.
  6. Pred potrditvijo sprememb zaženite composer verify.

Pri odpravljanju napake:

  1. Zajemite vhod, ki povzroča napako, kot scenarij.
  2. Potrdite, da referenčno orodje ustvari pričakovani izhod.
  3. Potrdite, da ga Greph ne ustvari.
  4. Odpravite napako.
  5. Potrdite, da se Greph zdaj ujema z referenčnim rezultatom.
  6. Zaženite composer verify.

Scenarij ostane v korpusu za vedno, zato se napaka ne more ponoviti, ne da bi test composer test:oracle (in composer verify) odpovedal.