Technical

Flaky testy a AI: automatická klasifikace za sekundu

V průměrné Cypress suite je 8–20 % testů flaky. Když vám spadne build, stojíte před otázkou: je to skutečný bug, nebo jen zase flake? Ruční triage zabere 10–15 minut na jedno selhání. AI to zvládne za sekundu.

Tenhle článek je hloubkový průchod stavbou automatického klasifikátoru — od definice flakiness přes trénovací data po integraci do CI.

Co přesně je flaky test

Test je flaky, když se při stejném vstupu chová nedeterministicky. Zdroje flakiness:

  1. Race conditions — DOM se vykresluje asynchronně, test byl rychlejší než UI.
  2. Síťová flakiness — API třetí strany mělo timeout a test spadl.
  3. Sdílený stav — předchozí test nechal databázi v jiném stavu.
  4. Prostředí — CI runner byl přetížený a animace trvala déle.
  5. Nedeterministická data — test závisí na aktuálním datu nebo náhodném ID.

Klasifikátor: signály, které AI využívá

Když test selže, máte k dispozici tyhle signály:

  • Chybová hláškaTimed out retrying after 4000ms vs. expected 'ACTIVE' to equal 'PENDING'. První je nejspíš flake, druhé nejspíš reálný bug.
  • Stack trace — selhání v cy.wait() vs. selhání v cy.contains().
  • Historická stabilita — spadl tenhle test za posledních 30 buildů 12×? Flake.
  • Souvisí commit s testovanou oblastí? — pokud diff mění checkout.tsx a selhal checkout test, je to nejspíš reálný bug.
  • Screenshot a video — pokud máte vizuální AI, porovnejte stav před a po. Když se UI změnilo, půjde nejspíš o commit s novou funkcí.

Architektura klasifikátoru

Pro náš produkční klasifikátor jsme použili tenhle 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

Jak data olabelovat (to je nejtěžší)

Trénovací data jsou nejkritičtější krok. Dvě ověřené cesty:

  1. Historická ruční triage — pokud máte dva a víc let záznamů z Cypress Dashboardu, dobré QA týmy failnuté testy často tagovaly jako „flaky" nebo „bug". Export a vyčištění = dataset.
  2. Labelování dopředu přes opakování — každé selhání automaticky zopakujte 3×. Když 2 ze 3 projdou, label = flaky. Když spadnou všechny tři, label = reálný bug. Po 4–6 týdnech máte zhruba 500 olabelovaných vzorků.

Integrace do CI

Náš hook v Jenkinsfile:

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 měsíců)

  • Čas ruční triage klesl z 12 minut na jedno selhání na 1,5 minuty (jen review klasifikátoru).
  • False positive rate (klasifikátor řekl bug, byl to flake): 4 %.
  • False negative rate (klasifikátor řekl flake, byl to bug): 7 % — tohle je kritické a je potřeba to minimalizovat.
  • Ušetřený čas QA týmu: ~35 hodin měsíčně.

Kdy vlastní klasifikátor nestavět

Pokud máte méně než 200 Cypress testů a flakiness pod 10 %, ROI je nulové. Doporučujeme:

  • Řešit flakiness na úrovni kódu testů (lepší waity, intercepty).
  • Používat Cypress Cloud (pokud ho platíte) — jeho detekce „Flaky Test" je bez ML, ale malému týmu stačí.

Chcete stejný přístup u vás? Napište nám — domluvíme 30minutový discovery call.