Testavimo strategija
merql naudoja oracle pagrįstą testavimo modelį. Kiekviename testavimo scenarijuje apibrėžiamas žinomas įvesčių rinkinys (trys duomenų bazės būsenos), deterministinis laukiamas rezultatas (oracle), o tikrasis sujungimo rezultatas palyginamas su juo. 32 scenarijai apima sklandžius sujungimus, konfliktus, tapatybės nustatymą, duomenų tipus, mastelį ir kraštinius atvejus.
# Run the full verification suite.
./bin/verify-all
Šiame puslapyje aprašytos komandos vykdomos iš merql saugyklos darbinės kopijos po
composer install. Kūrimo scenarijai, esantys bin/, scenarios/
korpusas ir testai nėra Composer paketo dalis. Kūrimo priklausomybėms reikia PHPUnit 13, kuriam būtina PHP 8.4 arba naujesnė versija, nors pati
biblioteka veikia su PHP 8.2.
Oracle pagrįstas testavimas
Esamo etaloninio įrankio, atliekančio trijų krypčių duomenų bazės sujungimą, nėra, todėl oracle apskaičiuojamas pagal žinomas įvestis, o ne generuojamas išoriniu įrankiu. Kiekvienas scenarijus turi deterministinį laukiamą rezultatą, kurį galima patikrinti logiškai:
- Paruošimas -- sukurkite tris duomenų bazės būsenas (base, ours, theirs) su žinomu turiniu.
- Oracle -- pagal žinomas įvestis apskaičiuokite laukiamą sujungimo rezultatą.
- Faktinis rezultatas -- atlikite merql trijų būsenų sujungimą.
- Palyginimas -- faktinis rezultatas turi tiksliai sutapti su laukiamu.
Known inputs (base, ours, theirs)
| |
Deterministic merql merge
computation
| |
Expected result Actual result
| |
-----> Compare <-----
|
Pass or Fail
Testų vykdymas
Visas patikrinimas
verify-all scenarijus yra galutinė patikra. Jis vykdo statinę analizę, kodavimo standartų patikras, PHPUnit testus ir oracle regresijos testų rinkinį:
./bin/verify-all
Kad darbas būtų laikomas baigtu, ši patikra turi būti sėkminga.
Oracle regresijos testų rinkinys
Paleiskite visus 32 scenarijus:
./bin/test-regression
Paleiskite vieną kategoriją:
./bin/test-regression --category clean
./bin/test-regression --category conflict
./bin/test-regression --category identity
Kategorijos yra katalogų pavadinimai, esantys scenarios/: clean, conflict, identity, types, scale ir edge. Nežinoma kategorija išveda No scenarios found ir sėkmingai baigia darbą. --category galima nurodyti kelis kartus, kad būtų paleistos kelios kategorijos.
Scenarijus taip pat priima --jobs, tačiau nepaiso reikšmės ir paleidžia scenarijus vieną po kito (#5).
Paleisti rodant minimalią išvestį (tik sėkmė arba nesėkmė):
./bin/test-regression --fast
Vienas scenarijus
Patikrinkite vieną scenarijų per visą apdorojimo grandinę:
./bin/test-scenario column-level-clean
Atskiri oracle žingsniai
./bin/oracle column-level-clean # Compute expected result
./bin/actual column-level-clean # Run merql, capture output
./bin/compare column-level-clean # Diff oracle vs actual
Vienetiniai testai
composer test:unit # Isolated component tests
composer test:integration # Integration tests (SQLite, plus MySQL when configured)
composer test # All PHPUnit suites
composer test:oracle # Oracle regression corpus (bin/test-regression)
composer verify # analyse + cs + test + test:oracle
composer test paleidžia tik PHPUnit. oracle PHPUnit rinkinys nurodo į tests/Oracle, kuriame yra scenarijų vykdyklės klasės, bet nėra testavimo atvejų, todėl 32 scenarijai paleidžiami tik per composer test:oracle, composer verify arba ./bin/verify-all.
MySQL integravimo testai praleidžiami, nebent MERQL_MYSQL_HOST, MERQL_MYSQL_DATABASE ir MERQL_MYSQL_USER (taip pat pasirinktinai MERQL_MYSQL_PASSWORD ir MERQL_MYSQL_PORT) nurodo testų duomenų bazę.
Kodo kokybė
composer cs # PSR-12 coding standards check
composer cs:fix # Auto-fix coding standards
composer analyse # PHPStan level 10 static analysis
Scenarijų kategorijos
clean (8 scenarijai)
Švarūs sujungimai be konfliktų. Abi pusės gali keisti duomenis, bet niekada nekeičia to paties to paties įrašo stulpelio.
| Scenarijus | Testas |
|---|---|
insert-only-theirs |
Jų pusė įterpė įrašų, mūsų pusė jų nepakeitė. |
update-only-theirs |
Jų pusė atnaujino įrašų, mūsų pusė jų nepakeitė. |
delete-only-theirs |
Jų pusė ištrynė įrašų, mūsų pusė jų nepakeitė. |
insert-only-ours |
Mūsų pusė įterpė įrašų, jų pusė jų nepakeitė. |
mixed-no-overlap |
Abi pusės pakeitė skirtingas lenteles arba įrašus. |
both-same-change |
Abi pusės atliko vienodus pakeitimus (konflikto nėra). |
column-level-clean |
Abi pusės pakeitė tą patį įrašą, bet skirtingus stulpelius. |
multi-table |
Pakeitimai keliose lentelėse. |
conflict (6 scenarijai)
Scenarijai, kuriuose turi kilti konfliktų.
| Scenarijus | Testas |
|---|---|
both-update-same-column |
Abi pusės pakeitė tą patį stulpelį į skirtingas reikšmes. |
update-vs-delete |
Viena pusė atnaujino, kita ištrynė tą patį įrašą. |
delete-vs-update |
Atvirkštinis atnaujinimo ir ištrynimo atvejis. |
both-insert-same-pk |
Abi pusės įterpė įrašą su tuo pačiu pirminiu raktu. |
multiple-conflicts |
Keli konfliktai viename sujungime. |
partial-conflict |
Kai kurie stulpeliai konfliktuoja, kiti sujungiami be konfliktų. |
identity (4 scenarijai)
Įrašų tapatybės kraštiniai atvejai.
| Scenarijus | Testas |
|---|---|
auto-increment |
Naujų įrašų ID skirtingose šakose skiriasi. |
natural-key |
Atitikmenys nustatomi pagal unikalius stulpelius, o ne pagal PK. |
composite-key |
Kelių stulpelių pirminis raktas. |
no-key |
Lentelė be pirminio rakto (atsarginis turinio maišos variantas). |
types (6 scenarijai)
Duomenų tipų apdorojimas visiems stulpelių tipams.
| Scenarijus | Testas |
|---|---|
text-columns |
VARCHAR, TEXT, LONGTEXT reikšmės. |
numeric-columns |
INT, DECIMAL, FLOAT reikšmės. |
date-columns |
DATE, DATETIME, TIMESTAMP reikšmės. |
json-columns |
JSON stulpelio sujungimas. |
blob-columns |
Dvejetainiai duomenys. |
null-handling |
Perėjimai iš NULL į reikšmę ir iš reikšmės į NULL. |
scale (4 scenarijai)
Našumas esant apkrovai.
| Scenarijus | Testas |
|---|---|
1k-rows |
1,000 įrašų. |
10k-rows |
10,000 įrašų. |
100k-rows |
100,000 įrašų. |
wide-table |
Lentelė su 50+ stulpelių. |
edge (4 scenarijai)
Kraštiniai atvejai ir ribinės sąlygos.
| Scenarijus | Testas |
|---|---|
empty-changeset |
Pakeitimų nėra vienoje arba abiejose pusėse. |
schema-mismatch |
Tarp momentinių kopijų pridėtas arba pašalintas stulpelis. |
encoding |
UTF-8, jaustukai, specialieji simboliai. |
large-text |
Labai didelės TEXT/LONGTEXT reikšmės. |
Scenarijaus struktūra
Kiekvienas scenarijus yra katalogas, esantis scenarios/<category>/<name>/, su scenario.json konfigūracija:
{
"name": "column-level-clean",
"category": "clean",
"description": "Both sides modify same row but different columns",
"tables": ["test_posts"],
"expectations": {
"conflicts": 0,
"operations": 3,
"changeset_match": "exact",
"merge_match": "exact",
"sql_match": "semantic"
}
}
Konfliktų scenarijuose tikėtini konfliktai išsamiai nurodomi:
{
"expectations": {
"conflicts": 1,
"conflict_details": [
{
"table": "test_posts",
"primary_key": {"id": 42},
"column": "title",
"ours_value": "Welcome",
"theirs_value": "Greetings"
}
]
}
}
ScenarioRunner apdorojimo grandinė
ScenarioRunner::run() koordinuoja vieną scenarijų:
OracleCapture::compute()iš scenarijaus JSON duomenų sukuria tris momentines kopijas ir paleidžia sujungimą.ScenarioComparator::compare()palygina sujungimo rezultatą suscenario.jsonnurodytomis tikėtinomis reikšmėmis.- Grąžina sėkmės arba nesėkmės būseną ir nesėkmės pranešimų sąrašą.
use Merql\Tests\Oracle\ScenarioRunner;
$result = ScenarioRunner::run($scenario);
// ['name' => 'column-level-clean', 'pass' => true, 'failures' => []]
ScenarioRunner::runAll() iš eilės paleidžia kiekvieną scenarijų:
$results = ScenarioRunner::runAll($scenarios);
Naujo scenarijaus pridėjimas
- Sukurkite katalogą:
scenarios/<category>/<name>/. - Sukurkite
scenario.jsonsu scenarijaus metaduomenimis ir tikėtinomis reikšmėmis. - JSON konfigūracijoje apibrėžkite tris duomenų bazės būsenas: bazinius duomenis, mūsų pakeitimus ir jų pakeitimus.
- Paleiskite scenarijų:
./bin/test-scenario <name>. - Patikrinkite visą rinkinį:
./bin/verify-all.
Kodo kokybės standartai
merql taiko:
- PHPStan 10 lygį -- griežtą statinę analizę be bazinės linijos išimčių.
- PSR-12 -- kodavimo standartus tikrina
phpcs. - Oracle regresija -- turi būti sėkmingi visi 32 scenarijai.
- Vienetiniai testai -- atskiri kiekvieno komponento testai.
verify-all scenarijus paeiliui atlieka visas keturias patikras. Dalinis patvirtinimas nepriimamas.
Nuolatinė integracija
CI kiekvieno siuntimo ir ištraukimo užklausos į main metu tikrina kodavimo standartus, PHPStan, composer test, integravimo testų rinkinį su MySQL 8.4 per mysqli, sujungimo primityvų aprėptį ir composer audit. Ji nevykdo oracle regresijos korpuso (#6), todėl prieš pasikliaudami pakeitimu paleiskite composer test:oracle arba ./bin/verify-all vietoje.