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.
# 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:
- Iestatīšana -- izveidojiet trīs datubāzes stāvokļus (pamatmomentuzņēmumu, mūsu un viņu) ar zināmu saturu.
- Etalons -- aprēķiniet sagaidāmo apvienošanas rezultātu no zināmajām ievaddatu kopām.
- Faktiskais rezultāts -- veiciet merql apvienošanu šajos trīs stāvokļos.
- Salīdzinājums -- faktiskajam rezultātam precīzi jāsakrīt ar sagaidāmo.
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:
./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:
./bin/test-regression
Palaidiet vienu kategoriju:
./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):
./bin/test-regression --fast
Atsevišķs scenārijs
Pārbaudiet vienu scenāriju visā izpildes ķēdē:
./bin/test-scenario column-level-clean
Atsevišķas oracle darbības
./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
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
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:
{
"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:
{
"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:
OracleCapture::compute()izveido trīs momentuzņēmumus no scenārija JSON datiem un izpilda sapludināšanu.ScenarioComparator::compare()salīdzina sapludināšanas rezultātu ar sagaidāmajām vērtībām failāscenario.json.- Atgriež izdošanās vai kļūmes rezultātu ar kļūmju ziņojumu sarakstu.
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:
$results = ScenarioRunner::runAll($scenarios);
Jauna scenārija pievienošana
- Izveidojiet direktoriju:
scenarios/<category>/<name>/. - Izveidojiet
scenario.jsonar scenārija metadatiem un sagaidāmajiem rezultātiem. - 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.
- Palaidiet scenāriju:
./bin/test-scenario <name>. - 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.