Ugrás a tartalomhoz

Tesztelési stratégia

A merql oracle-alapú tesztelési modellt használ. Minden tesztforgatókönyv meghatározott bemeneteket (három adatbázis-állapotot), determinisztikus elvárt eredményt (az oracle-t) határoz meg, majd ezt veti össze a tényleges merge kimenetével. A 32 forgatókönyv tiszta merge-eket, ütközéseket, azonosítási feloldást, adattípusokat, méretezhetőséget és szélső eseteket fed le.

Shell
# Run the full verification suite.
./bin/verify-all

Az ezen az oldalon szereplő parancsok a merql repository egy checkoutjából futtathatók, a composer install után. A bin/ fejlesztői szkriptek, a scenarios/ korpusz és a tesztek nem részei a Composer csomagnak. A fejlesztői függőségek között szerepel a PHPUnit 13, amelyhez PHP 8.4-es vagy újabb verziója szükséges, noha maga a könyvtár PHP 8.2-n fut.

Oracle-alapú tesztelés

Nincs olyan meglévő referenciaeszköz, amely háromutas adatbázis-merge-et végezne, ezért az oracle ismert bemenetekből, nem pedig külső eszközből származik. Minden forgatókönyvhöz tartozik egy determinisztikus elvárt eredmény, amely logikai úton ellenőrizhető:

  1. Előkészítés -- hozzon létre három adatbázis-állapotot (base, ours, theirs) ismert tartalommal.
  2. Oracle -- számítsa ki az elvárt merge-eredményt az ismert bemenetekből.
  3. Tényleges futtatás -- futtassa a merql merge műveletét a három állapoton.
  4. Összehasonlítás -- a tényleges eredménynek pontosan egyeznie kell az elvárttal.
Kód
Known inputs (base, ours, theirs)
         |                    |
    Deterministic          merql merge
    computation
         |                    |
    Expected result       Actual result
         |                    |
         -----> Compare <-----
                  |
            Pass or Fail

Tesztek futtatása

Teljes ellenőrzés

A verify-all szkript az utolsó ellenőrzési pont. Statikus elemzést, kódolási szabványok ellenőrzését, PHPUnit teszteket és oracle-regressziós tesztcsomagot futtat:

Shell
./bin/verify-all

Ezt teljesíteni kell, mielőtt bármely munka befejezettnek tekinthető.

Oracle-regressziós tesztcsomag

Futtassa mind a 32 forgatókönyvet:

Shell
./bin/test-regression

Futtasson egyetlen kategóriát:

Shell
./bin/test-regression --category clean
./bin/test-regression --category conflict
./bin/test-regression --category identity

A kategóriák a scenarios/ alatti könyvtárnevek: clean, conflict, identity, types, scale és edge. Ismeretlen kategória esetén kiírja a No scenarios found értéket, majd sikeresen kilép. A --category többször is megadható több kategória futtatásához.

A szkript a --jobs argumentumot is elfogadja, de az értékét figyelmen kívül hagyja, és egymás után futtatja a forgatókönyveket (#5).

Futtatás minimális kimenettel (csak sikeres/sikertelen):

Shell
./bin/test-regression --fast

Egyetlen forgatókönyv

Teszteljen egy forgatókönyvet a teljes folyamaton keresztül:

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

Egyedi oracle-lépések

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

Egységtesztek

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

A composer test csak a PHPUnit teszteket futtatja. A oracle PHPUnit tesztcsomag a tests/Oracle helyre mutat, amely a forgatókönyv-futtató osztályokat tartalmazza, de teszteseteket nem. Ezért a 32 forgatókönyv csak a composer test:oracle, a composer verify vagy a ./bin/verify-all használatával fut.

A MySQL integrációs tesztek kimaradnak, kivéve ha a MERQL_MYSQL_HOST, a MERQL_MYSQL_DATABASE és a MERQL_MYSQL_USER (valamint opcionálisan a MERQL_MYSQL_PASSWORD és a MERQL_MYSQL_PORT) egy tesztadatbázisra mutat.

Kódminőség

Shell
composer cs            # PSR-12 coding standards check
composer cs:fix        # Auto-fix coding standards
composer analyse       # PHPStan level 10 static analysis

Forgatókönyv-kategóriák

clean (8 forgatókönyv)

Tiszta merge-ek ütközések nélkül. Mindkét oldal módosíthat adatokat, de ugyanannak a sornak ugyanazt az oszlopát soha.

Forgatókönyv Teszt
insert-only-theirs A theirs sorokat szúrt be, az ours nem változott.
update-only-theirs A theirs sorokat frissített, az ours nem változott.
delete-only-theirs A theirs sorokat törölt, az ours nem változott.
insert-only-ours Az ours sorokat szúrt be, a theirs nem változott.
mixed-no-overlap Mindkét oldal különböző táblákat vagy sorokat módosított.
both-same-change Mindkét oldal azonos módosításokat végzett (nincs ütközés).
column-level-clean Mindkét oldal ugyanazt a sort módosította, de különböző oszlopokat.
multi-table Módosítások több táblában.

conflict (6 forgatókönyv)

Ütközést okozó forgatókönyvek.

Forgatókönyv Tesztek
both-update-same-column Mindkét oldal ugyanazt az oszlopot módosította, de eltérő értékre.
update-vs-delete Az egyik oldal frissítette, a másik törölte ugyanazt a sort.
delete-vs-update A frissítés és törlés fordított iránya.
both-insert-same-pk Mindkét oldal azonos elsődleges kulccsal szúrt be sort.
multiple-conflicts Több ütközés egyetlen összevonásban.
partial-conflict Egyes oszlopok ütköznek, mások összevonása problémamentes.

identity (4 forgatókönyv)

A sorazonosság szélső esetei.

Forgatókönyv Tesztek
auto-increment Az új sorok azonosítói eltérnek az ágak között.
natural-key Egyezés egyedi oszlopok alapján az elsődleges kulcs helyett.
composite-key Több oszlopból álló elsődleges kulcs.
no-key Elsődleges kulcs nélküli tábla (tartalomkivonat-alapú tartalékmegoldás).

types (6 forgatókönyv)

Adattípusok kezelése az összes oszloptípus esetén.

Forgatókönyv Tesztek
text-columns VARCHAR, TEXT, LONGTEXT értékek.
numeric-columns INT, DECIMAL, FLOAT értékek.
date-columns DATE, DATETIME, TIMESTAMP értékek.
json-columns JSON oszlop összevonása.
blob-columns Bináris adatok.
null-handling NULL értékről értékre, illetve értékről NULL-ra váltás.

scale (4 forgatókönyv)

Terhelés alatti teljesítmény.

Forgatókönyv Tesztek
1k-rows 1,000 sor.
10k-rows 10,000 sor.
100k-rows 100,000 sor.
wide-table Tábla több mint 50 oszloppal.

edge (4 forgatókönyv)

Szélső esetek és határfeltételek.

Forgatókönyv Tesztek
empty-changeset Nincs változás az egyik vagy mindkét oldalon.
schema-mismatch Oszlop hozzáadása vagy eltávolítása a pillanatképek között.
encoding UTF-8, emoji és speciális karakterek.
large-text Nagyon nagy TEXT/LONGTEXT értékek.

A forgatókönyvek felépítése

Minden forgatókönyv egy könyvtár a scenarios/<category>/<name>/ alatt, egy scenario.json konfigurációval:

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

Ütközési forgatókönyvek esetén a várt ütközések részletesen meg vannak adva:

JSON
{
    "expectations": {
        "conflicts": 1,
        "conflict_details": [
            {
                "table": "test_posts",
                "primary_key": {"id": 42},
                "column": "title",
                "ours_value": "Welcome",
                "theirs_value": "Greetings"
            }
        ]
    }
}

A ScenarioRunner folyamatlépései

A ScenarioRunner::run() egyetlen forgatókönyvet vezényel le:

  1. A OracleCapture::compute() létrehozza a három pillanatképet a forgatókönyv JSON adataiból, majd végrehajtja az összevonást.
  2. A ScenarioComparator::compare() összeveti az összevonás eredményét a scenario.json fájlban megadott várt értékekkel.
  3. Sikeres vagy sikertelen eredményt ad vissza a hibaüzenetek listájával.
PHP
use Merql\Tests\Oracle\ScenarioRunner;

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

A ScenarioRunner::runAll() sorban lefuttatja az összes forgatókönyvet:

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

Új forgatókönyv hozzáadása

  1. Hozzon létre egy könyvtárat: scenarios/<category>/<name>/.
  2. Hozza létre a scenario.json fájlt a forgatókönyv metaadataival és elvárásaival.
  3. Határozza meg a három adatbázis-állapotot a JSON konfigurációban: alapadatok, a saját módosításaink és az ő módosításaik.
  4. Futtassa a forgatókönyvet: ./bin/test-scenario <name>.
  5. Ellenőrizze a teljes tesztcsomagot: ./bin/verify-all.

Kódminőségi szabványok

A merql az alábbiakat írja elő:

  • PHPStan 10-es szint -- szigorú statikus elemzés, kivétel nélküli alapszabállyal.
  • PSR-12 -- a kódolási szabványok ellenőrzését a phpcs végzi.
  • Oracle-regresszió -- mind a 32 forgatókönyvnek sikeresen kell lefutnia.
  • Egységtesztek -- minden komponens elszigetelt tesztjei.

A verify-all parancsfájl egymás után futtatja mind a négy ellenőrzést. Részleges jóváhagyás nem fogadható el.

Folyamatos integráció

A CI minden, a main-re irányuló push és pull request esetén lefuttatja a kódolási szabványok ellenőrzését, a PHPStan-t, a composer test-t, az integrációs tesztcsomagot a MySQL 8.4-es verziójával, mysqli-n keresztül, az összevonási alapműveletek lefedettségi ellenőrzését, valamint a composer audit-t. Az oracle-regressziós tesztkorpuszt nem futtatja (#6), ezért a változtatásra hagyatkozás előtt futtassa helyben a composer test:oracle-t vagy a ./bin/verify-all-t.