Siirry sisältöön

Vertailutestaus

Kaikki kohteen Phasis toteutuspäätökset ratkaistaan yhden kysymyksen perusteella: tuottaako V8 saman tuloksen?

JavaScript-kielellä on hienovaraisia semantiikkoja — NaN !== NaN, -0 === 0, [1] + 1 === "11", ominaisuuksien luetteloinnin tarkka järjestys ja Promise-mikrotehtävien suoritusajankohta. Niiden johtaminen uudelleen määritystä lukemalla on hidasta ja altista virheille. Phasis ohittaa tämän käsittelemällä kohdetta Node.js (V8) vertailukohtana: kirjoita JS-skenaario, suorita se kohteessa V8 ja tallenna tulos oikeana; suorita se kohteessa Phasis, tallenna tulos uudelleen ja vertaa tuloksia.

Koodi
1. SETUP    → a JavaScript source file or snippet
2. ORACLE   → Node.js executes it, output captured as truth
3. ACTUAL   → Phasis executes it, output captured
4. COMPARE  → oracle vs actual, diff measures the gap

Kaksi testaustasoa

Taso 1 — mukautetut skenaariot

Jokainen kohteen scenarios/ skenaario on pieni JS-ohjelma, jonka tulos tunnetaan. Suorita yksi skenaario:

Shell
./bin/test-scenario operators/arithmetic

Suorita kaikki skenaariot, yksi luokka tai useita rinnakkain:

Shell
./bin/test-regression
./bin/test-regression --jobs 4
./bin/test-regression --category expressions

Päivitä vertailukohta (e.g esimerkiksi kohteen Node.js version päivityksen jälkeen):

Shell
./bin/oracle --refresh operators/arithmetic

Skenaariot on järjestetty ECMAScript-lukujen mukaan: literaalit, operaattorit, muuttujat, ohjausvirta, funktiot, objektit, taulukot, luokat, sisäänrakennetut toiminnot, virheet, yhteentoimivuus ja reunatapaukset.

Taso 2 — test262

Virallinen TC39-vaatimustenmukaisuustestisarja on lisätty git-alimoduulina kohteeseen test262/. Jokainen testi tarkistaa itse itsensä: se menee läpi, jos poikkeusta ei synny, ja epäonnistuu, jos poikkeus syntyy (tai päinvastoin kohteen negative testien kohdalla). Testiajoympäristö lataa kohteet assert.js ja sta.js ennen jokaista testiä.

Shell
./bin/test262                                    # full suite
./bin/test262 --category built-ins/Array         # subset
./bin/test262 --jobs 4                           # parallel
./bin/test262 --failures                         # one line per failing test
./bin/compat-report                              # full COMPAT.md + compat.json

Koko testisarjan vedos on kohteessa COMPAT.md, ja se luodaan uudelleen kohteella bin/compat-report. CI:n compat-matrix.yml-työnkulku suorittaa testit rinnakkain lohkoissa ja tallentaa tuloksen. Työnkulku käynnistetään käsin, ei jokaisella työntökerralla.

Paikallinen tarkistus ennen työntämistä

./bin/verify-all suorittaa CI:n edellyttämän laatutarkistuksen:

Koodi
=== PHPStan ===                  level 6, zero errors
=== Code Standards ===           PHPCS, zero warnings
=== PHPUnit ===                  unit suite passes
=== Oracle Regression ===        scenarios under `scenarios/` pass

Tämä ei yksin riitä — test262-testejä on ajettava otoksena kaikille muutoksille, jotka koskevat jäsennintä, tulkkia tai sisäänrakennettuja toimintoja. Jokaisen pull-pyynnön yhteydessä CI suorittaa kohteet PHPStan ja PHPCS, yksikkötestisarjan sekä vertailuregression. WPT- ja suosittujen pakettien testisarjat suoritetaan, kun pull-pyynnössä muutetaan kohdetta src/ tai niiden testitiedostoja. Koko test262-matriisi ei kuulu pull-pyyntöjen CI:hin, joten aja paikallisesti muutokseen liittyvät testiluokat.

Miksi tämä toimii

Kun kohdetta V8 käsitellään totuudenlähteenä, määrityksen lukeminen jää lähes kokonaan pois kehityssyklistä. Ero kohteeseen V8 verrattuna osoittaa aina Phasis-virheen — ei koskaan määrityksen monitulkintaisuutta, josta voisi väitellä. Kun korjaus on lisätty, vastaavista test262-testeistä tulee pysyviä regressiotestejä.

100 %:n läpäisyaste perustuu tähän käytäntöön: jokainen PR arvioidaan V8:n mukaan, CI hylkää regressiot oracle-, WPT- ja suosittujen pakettien testisarjoissa, ja test262-matriisi vahvistaa koko testisarjan tuloksen, kun se suoritetaan.