Pereiti prie turinio

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.

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

  1. Paruošimas -- sukurkite tris duomenų bazės būsenas (base, ours, theirs) su žinomu turiniu.
  2. Oracle -- pagal žinomas įvestis apskaičiuokite laukiamą sujungimo rezultatą.
  3. Faktinis rezultatas -- atlikite merql trijų būsenų sujungimą.
  4. Palyginimas -- faktinis rezultatas turi tiksliai sutapti su laukiamu.
Kodas
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į:

Shell
./bin/verify-all

Kad darbas būtų laikomas baigtu, ši patikra turi būti sėkminga.

Oracle regresijos testų rinkinys

Paleiskite visus 32 scenarijus:

Shell
./bin/test-regression

Paleiskite vieną kategoriją:

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

Shell
./bin/test-regression --fast

Vienas scenarijus

Patikrinkite vieną scenarijų per visą apdorojimo grandinę:

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

Atskiri oracle žingsniai

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

Vienetiniai testai

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 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ė

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

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"
    }
}

Konfliktų scenarijuose tikėtini konfliktai išsamiai nurodomi:

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

  1. OracleCapture::compute() iš scenarijaus JSON duomenų sukuria tris momentines kopijas ir paleidžia sujungimą.
  2. ScenarioComparator::compare() palygina sujungimo rezultatą su scenario.json nurodytomis tikėtinomis reikšmėmis.
  3. Grąžina sėkmės arba nesėkmės būseną ir nesėkmės pranešimų sąrašą.
PHP
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ų:

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

Naujo scenarijaus pridėjimas

  1. Sukurkite katalogą: scenarios/<category>/<name>/.
  2. Sukurkite scenario.json su scenarijaus metaduomenimis ir tikėtinomis reikšmėmis.
  3. JSON konfigūracijoje apibrėžkite tris duomenų bazės būsenas: bazinius duomenis, mūsų pakeitimus ir jų pakeitimus.
  4. Paleiskite scenarijų: ./bin/test-scenario <name>.
  5. 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.