Siirry sisältöön

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.

Shell
# 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:

  1. Valmistelu -- luo kolme tietokantatilaa (base, ours, theirs), joiden sisältö tunnetaan.
  2. Oraakkeli -- laske odotettu yhdistämistulos tunnettujen syötteiden perusteella.
  3. Toteutus -- suorita merql:n yhdistäminen näille kolmelle tilalle.
  4. Vertailu -- toteutuneen tuloksen on vastattava täsmälleen odotettua tulosta.
Koodi
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:

Shell
./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:

Shell
./bin/test-regression

Suorita yksittäinen luokka:

Shell
./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):

Shell
./bin/test-regression --fast

Yksittäinen skenaario

Testaa yksi skenaario koko putken läpi:

Shell
./bin/test-scenario column-level-clean

Yksittäiset oraakkelivaiheet

Shell
./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

Shell
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

Shell
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:

JSON
{
    "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:

JSON
{
    "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:

  1. OracleCapture::compute() muodostaa kolme tilannevedosta skenaarion JSON-tiedoista ja suorittaa yhdistämisen.
  2. ScenarioComparator::compare() tarkistaa yhdistämistuloksen kohteessa scenario.json määritettyjä odotusarvoja vasten.
  3. Palauttaa läpäisy/hylkäys-tuloksen ja luettelon virheilmoituksista.
PHP
use Merql\Tests\Oracle\ScenarioRunner;

$result = ScenarioRunner::run($scenario);
// ['name' => 'column-level-clean', 'pass' => true, 'failures' => []]

ScenarioRunner::runAll() suorittaa kaikki skenaariot järjestyksessä:

PHP
$results = ScenarioRunner::runAll($scenarios);

Uuden skenaarion lisääminen

  1. Luo hakemisto: scenarios/<category>/<name>/.
  2. Luo scenario.json skenaarion metatiedoille ja odotuksille.
  3. Määritä kolme tietokantatilaa JSON-määrityksessä: base-data, ours-muutokset ja theirs-muutokset.
  4. Suorita skenaario: ./bin/test-scenario <name>.
  5. 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.