Pereiti prie turinio

Testavimas pagal etalonus

Kiekvienas Phasis įgyvendinimo sprendimas priklauso nuo vieno klausimo: ar V8 pateikia tą patį rezultatą?

JavaScript semantika subtili — NaN !== NaN, -0 === 0, [1] + 1 === "11", tiksli savybių išvardijimo tvarka, Promise mikro užduočių vykdymo laikas. Iš naujo išvesti tai skaitant specifikaciją lėta ir nepatikima. Phasis šią problemą apeina laikydama Node.js (V8) etalonu: parašykite JS scenarijų, paleiskite jį per V8 ir užfiksuokite rezultatą kaip teisingą; tada paleiskite per Phasis, vėl užfiksuokite rezultatą ir palyginkite.

Kodas
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

Du testavimo lygiai

1 lygis — individualūs scenarijai

Kiekvienas scenarios/ scenarijus yra nedidelė JS programa su žinomu rezultatu. Paleiskite vieną scenarijų:

Shell
./bin/test-scenario operators/arithmetic

Paleiskite juos visus, vieną kategoriją arba lygiagrečiai:

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

Atnaujinkite etaloną (e.g. po Node.js versijos atnaujinimo):

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

Scenarijai suskirstyti pagal ECMAScript skyrius: literalai, operatoriai, kintamieji, valdymo srautas, funkcijos, objektai, masyvai, klasės, integruotos funkcijos, klaidos, sąveika ir kraštiniai atvejai.

2 lygis — test262

Oficialus TC39 atitikties testų rinkinys prijungtas kaip git submodulis kataloge test262/. Kiekvienas testas tikrina save: jis sėkmingas, jei nesukelia išimties, o jei sukelia — nepavyksta (arba atvirkščiai, jei tai negative testas). Prieš kiekvieną testą testų karkasas įkelia assert.js ir sta.js.

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

Viso rinkinio momentinė kopija saugoma COMPAT.md, ją iš naujo sukuria bin/compat-report. CI aplinkoje compat-matrix.yml darbo eiga paleidžia testus dalimis ir išsaugo rezultatą; ši darbo eiga paleidžiama rankiniu būdu, o ne po kiekvieno pakeitimo.

Vietinis patikrinimas prieš siunčiant pakeitimus

./bin/verify-all paleidžia CI taikomą kokybės patikrą:

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

Vien šio patikrinimo nepakanka — test262 taip pat reikia išbandyti su pavyzdžiais, jei keičiamas analizatorius, interpretatorius ar integruotos funkcijos. Kiekvienam pull request CI paleidžia PHPStan, PHPCS, vienetų testų rinkinį ir etalonų regresijos testą; WPT bei populiarių paketų rinkiniai paleidžiami, kai pull request pakeičia src/ arba jų fikstūras. Visa test262 matrica į pull request CI neįtraukta, todėl lokaliai išbandykite paveiktas kategorijas.

Kodėl tai veikia

Laikant V8 tiesos šaltiniu, kuriant programą beveik nebereikia skaityti specifikacijos. Nesutapimas su V8 visada reiškia Phasis klaidą — tai niekada nėra ginčytinas specifikacijos neaiškumas. Pritaikius pataisą, atitinkami test262 įrašai tampa nuolatiniais regresijos testais.

100 % sėkmingų testų dalis pasiekiama laikantis šios tvarkos: kiekvienas PR vertinamas pagal V8, CI atmeta regresijas etalonų, WPT ir populiarių paketų rinkiniuose, o test262 matrica patvirtina viso rinkinio rezultatą, kai ją paleidžiame.