Etalonprogrammas testēšana
Katru Phasis ieviešanas lēmumu nosaka viens jautājums: vai V8 rada tādu pašu izvadi?
JavaScript semantika ir niansēta — NaN !== NaN, -0 === 0, [1] + 1 === "11", precīza īpašību uzskaitīšanas secība un Promise mikrouzdevumu izpildes laiks. Atkārtoti izsecināt to, lasot specifikāciju, ir lēni un kļūdu iespējamība ir liela. Phasis to novērš, par etalonprogrammu izmantojot Node.js (V8): uzrakstiet JS scenāriju, palaidiet to caur V8 un saglabājiet izvadi kā patiesības avotu; palaidiet to caur Phasis, vēlreiz saglabājiet izvadi un salīdziniet tās.
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
Divi testēšanas līmeņi
1. līmenis — pielāgoti scenāriji
Katrs scenarios/ scenārijs ir neliela JS programma ar zināmu izvadi. Palaidiet vienu scenāriju:
./bin/test-scenario operators/arithmetic
Palaidiet visus scenārijus, tikai vienu kategoriju vai paralēli:
./bin/test-regression
./bin/test-regression --jobs 4
./bin/test-regression --category expressions
Atjauniniet etalonprogrammu (e.g, piemēram, pēc Node.js versijas atjaunināšanas):
./bin/oracle --refresh operators/arithmetic
Scenāriji ir sakārtoti pēc ECMAScript nodaļām: literāļi, operatori, mainīgie, vadības plūsma, funkcijas, objekti, masīvi, klases, iebūvētās funkcijas, kļūdas, sadarbspēja un robežgadījumi.
2. līmenis — test262
Oficiālā TC39 atbilstības testu kopa ir pievienota kā git apakšmodulis mapē test262/. Katrs tests pārbauda pats sevi: tas ir sekmīgs, ja neizmet izņēmumu, un neiztur, ja to izmet (vai otrādi — negative testos). Pirms katra testa ietvars ielādē assert.js un sta.js.
./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
Pilnā testu kopuma momentuzņēmums atrodas COMPAT.md; to no jauna ģenerē bin/compat-report. CI vidē compat-matrix.yml darbplūsma to izpilda pa daļām un pievieno rezultātu; šī darbplūsma tiek palaista manuāli, nevis pēc katras koda nosūtīšanas.
Lokālā pārbaude pirms koda nosūtīšanas
./bin/verify-all izpilda CI noteikto kvalitātes pārbaudi:
=== PHPStan === level 6, zero errors
=== Code Standards === PHPCS, zero warnings
=== PHPUnit === unit suite passes
=== Oracle Regression === scenarios under `scenarios/` pass
Ar to vien nepietiek — test262 papildus jāpārbauda izlases veidā ikvienām izmaiņām, kas skar parsētāju, interpretatoru vai iebūvētās funkcijas. Katrā vilkšanas pieprasījumā CI palaiž PHPStan, PHPCS, vienību testu kopu un etalonprogrammas regresijas testu; WPT un populāro pakotņu testu kopas tiek palaistas, ja vilkšanas pieprasījumā mainās src/ vai to testa paraugi. Pilnā test262 matrica nav iekļauta vilkšanas pieprasījumu CI, tāpēc lokāli pārbaudiet ietekmētās kategorijas.
Kāpēc tas darbojas
Izmantojot V8 kā patiesības avotu, izstrādes procesā gandrīz vairs nav jālasa specifikācija. Nesakritība ar V8 vienmēr norāda uz Phasis kļūdu — tā nekad nav apspriežama specifikācijas neskaidrība. Kad labojums ir pievienots, attiecīgie test262 ieraksti kļūst par pastāvīgiem regresijas testiem.
100 % sekmīgo testu rādītājs ir šīs disciplīnas rezultāts: katrs vilkšanas pieprasījums tiek vērtēts pret V8, CI noraida regresijas etalonprogrammas, WPT un populāro pakotņu testu kopās, bet test262 matrica, kad tā tiek palaista, apstiprina pilnā testu kopuma rezultātu.