Testausstrategia
merql käyttää oraakkelipohjaista testausmallia. Kukin testiskenaario määrittää tunnetut syötteet (kolme tietokantatilaa), deterministisen odotetun tuloksen (oraakkelin) ja vertaa toteutunutta yhdistämistulosta tähän odotukseen. 32 skenaariota kattaa puhtaat yhdistämiset, ristiriidat, identiteetin ratkaisun, tietotyypit, skaalan ja poikkeustapaukset.
# Run the full verification suite.
./bin/verify-all
Tämän sivun komennot suoritetaan merql-tietovaraston kloonissa komennon
composer install jälkeen. Kehitysskriptit kohteessa bin/, scenarios/-korpus ja testit eivät kuulu Composer-pakettiin. Kehitysriippuvuuksiin kuuluu myös PHPUnit 13, joka vaatii version PHP 8.4 tai uudemman, vaikka kirjasto toimii versiolla PHP 8.2.
Oraakkelipohjainen testaus
Olemassa ei ole vertailutyökalua, joka tekisi kolmitieyhdistämisen tietokantojen välillä. Siksi oraakkeli lasketaan tunnettujen syötteiden perusteella ulkoisen työkalun luomisen sijaan. Jokaisella skenaariolla on deterministinen odotettu tulos, jonka oikeellisuus voidaan varmistaa päättelyn avulla:
- Valmistelu -- luo kolme tietokantatilaa (base, ours, theirs), joiden sisältö tunnetaan.
- Oraakkeli -- laske odotettu yhdistämistulos tunnettujen syötteiden perusteella.
- Toteutus -- suorita merql:n yhdistäminen näille kolmelle tilalle.
- Vertailu -- toteutuneen tuloksen on vastattava täsmälleen odotettua tulosta.
Known inputs (base, ours, theirs)
| |
Deterministic merql merge
computation
| |
Expected result Actual result
| |
-----> Compare <-----
|
Pass or Fail
Testien suorittaminen
Täysi varmennus
Skripti verify-all on viimeinen tarkistusvaihe. Se suorittaa staattisen analyysin, koodausstandardien tarkistukset, PHPUnit-testit ja oraakkelin regressiotestikokonaisuuden:
./bin/verify-all
Tämän on läpäistävä, ennen kuin mitään työtä voidaan pitää valmiina.
Oraakkelin regressiotestikokonaisuus
Suorita kaikki 32 skenaariota:
./bin/test-regression
Suorita yksittäinen luokka:
./bin/test-regression --category clean
./bin/test-regression --category conflict
./bin/test-regression --category identity
Luokat ovat kohteen scenarios/ hakemistonimiä: clean, conflict,
identity, types, scale ja edge. Tuntematon luokka tulostaa
No scenarios found ja päättyy onnistuneesti. --category voidaan toistaa
usean luokan suorittamiseksi.
Skripti hyväksyy myös argumentin --jobs, mutta sivuuttaa sen arvon ja suorittaa skenaariot peräkkäin (#5).
Suorita vähäisellä tulosteella (vain läpäisy/hylkäys):
./bin/test-regression --fast
Yksittäinen skenaario
Testaa yksi skenaario koko putken läpi:
./bin/test-scenario column-level-clean
Yksittäiset oraakkelivaiheet
./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
Yksikkötestit
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 suorittaa vain kohteen PHPUnit. Kohteen oracle PHPUnit-testikokonaisuus osoittaa kohteeseen tests/Oracle, jossa ovat skenaariosuorittimen luokat mutta ei testitapauksia. Siksi 32 skenaariota suoritetaan vain kohteiden composer test:oracle, composer verify tai ./bin/verify-all kautta.
MySQL-integraatiotestit ohitetaan, elleivät MERQL_MYSQL_HOST, MERQL_MYSQL_DATABASE ja MERQL_MYSQL_USER (sekä haluttaessa MERQL_MYSQL_PASSWORD ja MERQL_MYSQL_PORT) osoita testitietokantaan.
Koodin laatu
composer cs # PSR-12 coding standards check
composer cs:fix # Auto-fix coding standards
composer analyse # PHPStan level 10 static analysis
Skenaarioluokat
clean (8 skenaariota)
Puhtaat yhdistämiset ilman ristiriitoja. Kumpikin puoli voi muuttaa tietoja, mutta ei koskaan saman rivin samaa saraketta.
| Skenaario | Testit |
|---|---|
insert-only-theirs |
Theirs lisäsi rivejä, ours ei muuttunut. |
update-only-theirs |
Theirs päivitti rivejä, ours ei muuttunut. |
delete-only-theirs |
Theirs poisti rivejä, ours ei muuttunut. |
insert-only-ours |
Ours lisäsi rivejä, theirs ei muuttunut. |
mixed-no-overlap |
Molemmat muuttivat eri tauluja tai rivejä. |
both-same-change |
Molemmat tekivät samat muutokset (ei ristiriitaa). |
column-level-clean |
Molemmat muuttivat saman rivin eri sarakkeita. |
multi-table |
Muutoksia useissa tauluissa. |
conflict (6 skenaariota)
Skenaariot, joiden on tuotettava ristiriitoja.
| Skenaario | Testit |
|---|---|
both-update-same-column |
Molemmat muuttivat saman sarakkeen eri arvoiksi. |
update-vs-delete |
Toinen päivitti rivin, toinen poisti saman rivin. |
delete-vs-update |
Päivityksen ja poiston vastakkainen järjestys. |
both-insert-same-pk |
Molemmat lisäsivät rivin samalla pääavaimella. |
multiple-conflicts |
Useita ristiriitoja yhdessä yhdistämisessä. |
partial-conflict |
Osa sarakkeista on ristiriidassa, muut yhdistyvät ongelmitta. |
identity (4 skenaariota)
Rivi-identiteetin poikkeustapaukset.
| Skenaario | Testit |
|---|---|
auto-increment |
Uusilla riveillä on eri tunnisteet eri haaroissa. |
natural-key |
Yhdistäminen yksilöllisten sarakkeiden, ei PK:n, perusteella. |
composite-key |
Monisarakkeinen pääavain. |
no-key |
Taulu ilman pääavainta (sisältötiivisteeseen perustuva vararatkaisu). |
types (6 skenaariota)
Tietotyyppien käsittely kaikissa saraketyypeissä.
| Skenaario | Testit |
|---|---|
text-columns |
VARCHAR-, TEXT- ja LONGTEXT-arvot. |
numeric-columns |
INT-, DECIMAL- ja FLOAT-arvot. |
date-columns |
DATE-, DATETIME- ja TIMESTAMP-arvot. |
json-columns |
JSON-sarakkeen yhdistäminen. |
blob-columns |
Binääridata. |
null-handling |
Siirtymät NULL-arvosta arvoon ja arvosta NULL-arvoon. |
scale (4 skenaariota)
Suorituskyky kuormitettuna.
| Skenaario | Testit |
|---|---|
1k-rows |
1,000 riviä. |
10k-rows |
10,000 riviä. |
100k-rows |
100,000 riviä. |
wide-table |
Taulu, jossa on yli 50 saraketta. |
edge (4 skenaariota)
Poikkeustapaukset ja rajaehdot.
| Skenaario | Testit |
|---|---|
empty-changeset |
Ei muutoksia toisella tai kummallakaan puolella. |
schema-mismatch |
Sarake lisätty tai poistettu tilannevedosten välillä. |
encoding |
UTF-8, emoji ja erikoismerkit. |
large-text |
Erittäin suuria TEXT- ja LONGTEXT-arvoja. |
Skenaarion rakenne
Kukin skenaario on hakemisto kohteessa scenarios/<category>/<name>/, ja siinä on scenario.json-määritys:
{
"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"
}
}
Ristiriitaskenaarioissa odotetut ristiriidat määritetään yksityiskohtaisesti:
{
"expectations": {
"conflicts": 1,
"conflict_details": [
{
"table": "test_posts",
"primary_key": {"id": 42},
"column": "title",
"ours_value": "Welcome",
"theirs_value": "Greetings"
}
]
}
}
ScenarioRunner-putki
ScenarioRunner::run() orkestroi yhden skenaarion:
OracleCapture::compute()muodostaa kolme tilannevedosta skenaarion JSON-tiedoista ja suorittaa yhdistämisen.ScenarioComparator::compare()tarkistaa yhdistämistuloksen kohteessascenario.jsonmääritettyjä odotusarvoja vasten.- Palauttaa läpäisy/hylkäys-tuloksen ja luettelon virheilmoituksista.
use Merql\Tests\Oracle\ScenarioRunner;
$result = ScenarioRunner::run($scenario);
// ['name' => 'column-level-clean', 'pass' => true, 'failures' => []]
ScenarioRunner::runAll() suorittaa kaikki skenaariot järjestyksessä:
$results = ScenarioRunner::runAll($scenarios);
Uuden skenaarion lisääminen
- Luo hakemisto:
scenarios/<category>/<name>/. - Luo
scenario.jsonskenaarion metatiedoille ja odotuksille. - Määritä kolme tietokantatilaa JSON-määrityksessä: base-data, ours-muutokset ja theirs-muutokset.
- Suorita skenaario:
./bin/test-scenario <name>. - Varmista koko testikokonaisuus:
./bin/verify-all.
Koodin laatustandardit
merql edellyttää seuraavaa:
- PHPStan taso 10 -- tiukka staattinen analyysi ilman poikkeuksia perustasoon.
- PSR-12 -- koodausstandardit tarkistetaan työkalulla
phpcs. - Oraakkelin regressiotestit -- kaikkien 32 skenaarion on läpäistävä.
- Yksikkötestit -- kunkin komponentin erilliset testit.
Skripti verify-all suorittaa kaikki neljä tarkistusta peräkkäin. Osittaista hyväksyntää ei anneta.
Jatkuva integraatio
Jatkuva integraatio suorittaa jokaisella main-tietovaraston pushilla ja pull requestilla koodausstandardien tarkistukset, PHPStan-, composer test- ja integraatiotestit versiota MySQL 8.4 vasten mysqli:n kautta, yhdistämisen perustoimintojen testit sekä composer audit. Se ei suorita oraakkelin regressiotestikorpusta (#6), joten suorita paikallisesti composer test:oracle tai ./bin/verify-all ennen muutokseen luottamista.