Flaky testy a AI: automatická klasifikace za sekundu
V priemernej Cypress suite je 8–20 % testov flaky. Keď váš build fail-ne, stojíš pred otázkou: je to skutočný bug, alebo len znova spadlý flakeout? Manuálne triage trvá 10–15 minút per fail. AI to robí za sekundu.
Tento článok je deep-dive do konštrukcie automatického klasifikátora — od definície flakiness cez tréningové dáta po CI integráciu.
Čo je flaky test presne
Test je flaky, keď má nedeterministické správanie pri rovnakom vstupe. Zdroje flakiness:
- Race conditions — DOM sa rendruje asynchrónne, test bežal rýchlejšie než UI.
- Network flakiness — 3. stranový API mal timeout, test padol.
- Shared state — predchádzajúci test nechal DB v inom stave.
- Environmentálne — CI runner bol preťažený, animácia trvala dlhšie.
- Nedeterministické dáta — test závisí od aktuálneho dátumu alebo random ID.
Klasifikátor: signály, ktoré AI využíva
Keď test fail-ne, máte k dispozícii tieto data-signály:
- Chybová hláška —
Timed out retrying after 4000msvs.expected 'ACTIVE' to equal 'PENDING'. Prvé je pravdepodobne flake, druhé pravdepodobne reálny bug. - Stack trace — fail v
cy.wait()vs. fail vcy.contains(). - Historická stabilita — padal tento test za posledných 30 buildov 12×? Flake.
- Commit súvisí s testovanou oblasťou? — ak diff mení
checkout.tsxa zlyhal checkout test, pravdepodobne reálny bug. - Screenshot a video — ak máte Visual AI, porovnaj pred/po. Ak sa UI zmenilo, pravdepodobne feature commit.
Architektúra klasifikátora
Pre náš produkčný klasifikátor sme použili tento stack:
Zdroje dát: - Cypress Dashboard API (história behu) - Git commit hash + diff - JUnit XML výstup - Screenshots + video Feature extraction (Python): - error_message_category (ML klasifikácia z textu) - test_stability_last_30d (historical ratio) - files_changed_relevance (Jaccard similarity) - timing_anomaly (z-score behu voči priemeru) Model: - Gradient Boosting (XGBoost) - Tréningová množina: ~8000 manuálne označených failov - Accuracy: 88% / Precision flake: 92% Inference: - REST endpoint (AWS Lambda) - Latency: ~120ms p50 - Invoked z Jenkins post-build step
Ako dáta označiť (to je najťažšie)
Tréningová dáta sú najkritickejší krok. Dve overené cesty:
- Historické manuálne triage — ak máte 2+ roky Cypress Dashboard záznamov, dobrí QA tímy často tagovali failed testy ako „flaky" alebo „bug". Si export + clean = dataset.
- Forward labeling cez re-run — každý fail automaticky retry 3×. Ak 2/3 prešli, label = flaky. Ak 3/3 padli, label = real bug. Po 4–6 týždňoch máte ~500 labeled samples.
CI integrácia
Náš Jenkinsfile hook:
post {
failure {
script {
def failedTests = readJSON file: 'cypress/reports/junit.json'
def response = httpRequest(
url: 'https://classifier.internal/classify',
httpMode: 'POST',
contentType: 'APPLICATION_JSON',
requestBody: groovy.json.JsonOutput.toJson([
failed_tests: failedTests,
commit_sha: env.GIT_COMMIT,
build_id: env.BUILD_NUMBER,
])
)
def results = readJSON text: response.content
results.each { r ->
if (r.classification == 'flake' && r.confidence > 0.85) {
// Auto-retry, no human needed
sh "npx cypress run --spec '${r.test_file}'"
} else {
// Create Jira ticket
slackSend(channel: '#qa-alerts', message: "🐛 Real bug: ${r.test_name}")
}
}
}
}
}
Výsledky u klienta (6 mesiacov)
- Manuálny triage time klesol z 12 min/fail na 1.5 min/fail (len review klasifikátora).
- False positive rate (klasifikátor povedal bug, bol to flake): 4 %.
- False negative rate (klasifikátor povedal flake, bol to bug): 7 % — toto je kritické, má sa minimalizovať.
- Ušetrený čas QA tímu: ~35 hodín mesačne.
Keď NEkónštuovať vlastný klasifikátor
Ak máte menej ako 200 Cypress testov a flakiness rate pod 10 %, ROI je nulový. Odporúčame:
- Riešiť flakiness na úrovni kódu testov (lepšie waits, intercepty).
- Používať Cypress Cloud (ak platíte) — ich „Flaky Test" detekcia je bez ML, ale pre malé tímy stačí.
Chcete rovnaký prístup u vás? Napište nám — dohodneme 30minutový discovery call.