Pāriet uz saturu

Testēšanas stratēģija

merql izmanto uz etalonu balstītu testēšanas modeli. Katrā testa scenārijā ir noteikta zināma ievaddatu kopa (trīs datubāzes stāvokļi), deterministisks sagaidāmais rezultāts (etalons), un faktiskā apvienošanas izvade tiek salīdzināta ar šo gaidāmo rezultātu. 32 scenāriji aptver tīru apvienošanu, konfliktus, identitātes noteikšanu, datu tipus, mērogu un robežgadījumus.

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

Šajā lapā minētās komandas jāpalaiž no merql repozitorija darba kopijas pēc composer install. Izstrādes skripti bin/, scenarios/ korpuss un testi nav iekļauti Composer pakotnē. Izstrādes atkarībās ietilpst PHPUnit 13, kam nepieciešama PHP 8.4 vai jaunāka versija, lai gan pati bibliotēka darbojas ar PHP 8.2.

Uz etalonu balstīta testēšana

Nav pieejams esošs atsauces rīks, kas veiktu trīspusēju datubāzu apvienošanu, tāpēc etalons tiek aprēķināts no zināmajām ievaddatu kopām, nevis ģenerēts ar ārēju rīku. Katrā scenārijā ir deterministisks sagaidāmais rezultāts, ko var pārbaudīt pēc loģikas:

  1. Iestatīšana -- izveidojiet trīs datubāzes stāvokļus (pamatmomentuzņēmumu, mūsu un viņu) ar zināmu saturu.
  2. Etalons -- aprēķiniet sagaidāmo apvienošanas rezultātu no zināmajām ievaddatu kopām.
  3. Faktiskais rezultāts -- veiciet merql apvienošanu šajos trīs stāvokļos.
  4. Salīdzinājums -- faktiskajam rezultātam precīzi jāsakrīt ar sagaidāmo.
Kods
Known inputs (base, ours, theirs)
         |                    |
    Deterministic          merql merge
    computation
         |                    |
    Expected result       Actual result
         |                    |
         -----> Compare <-----
                  |
            Pass or Fail

Testu palaišana

Pilna pārbaude

Skripts verify-all ir pēdējais pārbaudes posms. Tas veic statisko analīzi, pārbauda kodēšanas standartus, PHPUnit testus un etalona regresijas testu kopu:

Apvalks
./bin/verify-all

Pirms jebkādu darbu uzskata par pabeigtu, šai pārbaudei ir jāizdodas.

Etalona regresijas testu kopa

Palaidiet visus 32 scenārijus:

Apvalks
./bin/test-regression

Palaidiet vienu kategoriju:

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

Kategorijas ir direktoriju nosaukumi mapē scenarios/: clean, conflict, identity, types, scale un edge. Nezināmai kategorijai tiek parādīts No scenarios found, un izpilde beidzas veiksmīgi. --category var norādīt atkārtoti, lai palaistu vairākas kategorijas.

Skripts pieņem arī --jobs, taču ignorē norādīto vērtību un palaiž scenārijus vienu pēc otra (#5).

Palaidiet ar minimālu izvadi (tikai pass/fail):

Apvalks
./bin/test-regression --fast

Atsevišķs scenārijs

Pārbaudiet vienu scenāriju visā izpildes ķēdē:

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

Atsevišķas oracle darbības

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

Vienību testi

Apvalks
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 izpilda tikai PHPUnit. oracle PHPUnit komplekts norāda uz tests/Oracle, kurā ir scenāriju izpildītāja klases, bet nav testpiemēru, tāpēc 32 scenāriji tiek izpildīti tikai caur composer test:oracle, composer verify vai ./bin/verify-all.

MySQL integrācijas testi tiek izlaisti, ja vien MERQL_MYSQL_HOST, MERQL_MYSQL_DATABASE un MERQL_MYSQL_USER (kā arī pēc izvēles MERQL_MYSQL_PASSWORD un MERQL_MYSQL_PORT) nenorāda uz testa datubāzi.

Koda kvalitāte

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

Scenāriju kategorijas

clean (8 scenāriji)

Tīras sapludināšanas bez konfliktiem. Abas puses var mainīt datus, bet nekad vienu un to pašu tās pašas rindas kolonnu.

Scenārijs Pārbaudes
insert-only-theirs Viņu puses ievietotās rindas, mūsu puse nemainīta.
update-only-theirs Viņu puses atjauninātās rindas, mūsu puse nemainīta.
delete-only-theirs Viņu puses dzēstās rindas, mūsu puse nemainīta.
insert-only-ours Mūsu puses ievietotās rindas, viņu puse nemainīta.
mixed-no-overlap Abas puses mainīja dažādas tabulas vai rindas.
both-same-change Abas puses veica identiskas izmaiņas (bez konflikta).
column-level-clean Abas puses mainīja vienu un to pašu rindu, bet dažādas kolonnas.
multi-table Izmaiņas vairākās tabulās.

conflict (6 scenāriji)

Scenāriji, kuros jārodas konfliktiem.

Scenārijs Pārbaudes
both-update-same-column Abas puses mainīja vienu un to pašu kolonnu uz dažādām vērtībām.
update-vs-delete Viena puse atjaunināja, otra dzēsa to pašu rindu.
delete-vs-update Pretējs atjaunināšanas un dzēšanas virziens.
both-insert-same-pk Abas puses ievietoja rindu ar vienu un to pašu primāro atslēgu.
multiple-conflicts Vienā sapludināšanā ir vairāki konflikti.
partial-conflict Dažās kolonnās ir konflikti, bet citas tiek sapludinātas bez konfliktiem.

identity (4 scenāriji)

Rindu identitātes robežgadījumi.

Scenārijs Pārbaudes
auto-increment Jaunām rindām dažādos atzaros ir atšķirīgi ID.
natural-key Atbilstību nosaka pēc unikālajām kolonnām, nevis PK.
composite-key Vairāku kolonnu primārā atslēga.
no-key Tabula bez primārās atslēgas (rezerves variants — satura jaucējvērtība).

types (6 scenāriji)

Datu tipu apstrāde visiem kolonnu tipiem.

Scenārijs Pārbaudes
text-columns VARCHAR, TEXT, LONGTEXT vērtības.
numeric-columns INT, DECIMAL, FLOAT vērtības.
date-columns DATE, DATETIME, TIMESTAMP vērtības.
json-columns JSON kolonnu sapludināšana.
blob-columns Binārie dati.
null-handling Pārejas no NULL uz vērtību un no vērtības uz NULL.

scale (4 scenāriji)

Veiktspēja slodzes apstākļos.

Scenārijs Pārbaudes
1k-rows 1,000 rindas.
10k-rows 10,000 rindas.
100k-rows 100,000 rindas.
wide-table Tabula ar 50+ kolonnām.

edge (4 scenāriji)

Robežgadījumi un robežnosacījumi.

Scenārijs Pārbaudes
empty-changeset Vienā vai abās pusēs nav izmaiņu.
schema-mismatch Kolonna pievienota vai noņemta starp momentuzņēmumiem.
encoding UTF-8, emocijzīmes, speciālās rakstzīmes.
large-text Ļoti lielas TEXT/LONGTEXT vērtības.

Scenārija struktūra

Katrs scenārijs ir direktorijs zem scenarios/<category>/<name>/ ar scenario.json konfigurāciju:

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

Konfliktu scenārijos sagaidāmie konflikti ir detalizēti norādīti:

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

ScenarioRunner izpildes ķēde

ScenarioRunner::run() koordinē viena scenārija izpildi:

  1. OracleCapture::compute() izveido trīs momentuzņēmumus no scenārija JSON datiem un izpilda sapludināšanu.
  2. ScenarioComparator::compare() salīdzina sapludināšanas rezultātu ar sagaidāmajām vērtībām failā scenario.json.
  3. Atgriež izdošanās vai kļūmes rezultātu ar kļūmju ziņojumu sarakstu.
PHP
use Merql\Tests\Oracle\ScenarioRunner;

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

ScenarioRunner::runAll() izpilda katru scenāriju pēc kārtas:

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

Jauna scenārija pievienošana

  1. Izveidojiet direktoriju: scenarios/<category>/<name>/.
  2. Izveidojiet scenario.json ar scenārija metadatiem un sagaidāmajiem rezultātiem.
  3. Definējiet trīs datubāzes stāvokļus konfigurācijā JSON: bāzes datus, mūsu puses izmaiņas un viņu puses izmaiņas.
  4. Palaidiet scenāriju: ./bin/test-scenario <name>.
  5. Pārbaudiet visu komplektu: ./bin/verify-all.

Koda kvalitātes standarti

merql nodrošina:

  • PHPStan līmenis 10 -- stingra statiskā analīze bez bāzes izņēmumiem.
  • PSR-12 -- kodēšanas standartus pārbauda phpcs.
  • Oracle regresijas testi -- jāiztur visi 32 scenāriji.
  • Vienību testi -- izolēti katra komponenta testi.

Skripts verify-all secīgi izpilda visas četras pārbaudes. Daļēja apstiprināšana netiek pieņemta.

Nepārtraukta integrācija

CI katrā nosūtīšanas reizē un vilkšanas pieprasījumā uz main izpilda kodēšanas standartu pārbaudes, PHPStan, composer test, integrācijas testu komplektu ar MySQL 8.4, izmantojot mysqli, sapludināšanas primitīvu pārklājumu un composer audit. Tā neizpilda oracle regresijas testu kopu (#6), tāpēc pirms paļaušanās uz izmaiņām lokāli palaidiet composer test:oracle vai ./bin/verify-all.