Come distinguo un vero difetto da un test instabile?
Esegui il test più volte disattivando i tentativi automatici e conta i risultati. Un vero difetto causa lo stesso errore a ogni esecuzione, mentre un test instabile riesce in alcune esecuzioni e fallisce in altre senza che nulla sia cambiato. L'esempio qui sotto fa esattamente questo su qualsiasi macchina con Playwright, poi mostra come Nexus Studio gestisce ciascun risultato.
A cura del team di Nexus Studio, Verdict System LLC. 27 ottobre 2026.
Come posso distinguerli in un minuto?
Esegui il test più volte di seguito disattivando i tentativi automatici. Playwright lo fa con due opzioni: --retries=0, così un nuovo tentativo non può nascondere un errore, e --repeat-each=6, che esegue ogni test sei volte. Poi conta i risultati di ciascun test.
- È fallito ogni volta: trattalo come un difetto finché non puoi dimostrare il contrario. Un errore a ogni esecuzione può comunque dipendere dall'ambiente, ad esempio da una richiesta bloccata o da un host irraggiungibile, quindi leggi prima l'errore.
- È riuscito in alcune esecuzioni ed è fallito in altre: è instabile. Il codice e il test non sono cambiati tra un'esecuzione e l'altra, quindi c'è qualcosa di instabile nell'applicazione o nel test.
- È riuscito ogni volta: per ora non emerge nulla. Un difetto che si manifesta una volta ogni cinquanta esecuzioni richiede più esecuzioni, oppure un'occhiata alla cronologia del test.
Posso provarlo con un esempio eseguibile?
Salva questo codice come bug-or-flaky.spec.js. Il primo test simula un'instabilità: fallisce un'esecuzione su tre. Il secondo test rappresenta un vero difetto: la pagina dice "Welcome" e il test si aspetta "Welcome back", quindi nessuna esecuzione può riuscire.
import { test, expect } from '@playwright/test';
// Fails on its first attempt of every third run, passes otherwise: a simulated flake.
test('flaky: a slow load now and then', async ({ page }, info) => {
await page.setContent('<h1>Welcome</h1>');
expect((info.repeatEachIndex + info.retry) % 3, 'simulated slow load').not.toBe(0);
});
// Fails the same way every time: the heading says "Welcome", the test expects "Welcome back".
test('real bug: wrong heading', async ({ page }) => {
await page.setContent('<h1>Welcome</h1>');
await expect(page.locator('h1')).toHaveText('Welcome back', { timeout: 300 });
});
Eseguilo sei volte disattivando i tentativi automatici:
npx playwright test --retries=0 --repeat-each=6
Playwright termina con 8 test falliti e 4 riusciti. È il conteggio per ciascun test a rispondere alla domanda, ed è ciò che il reporter a elenco ha stampato, riga per riga:
flaky: a slow load now and then 4 passed, 2 failed
real bug: wrong heading 0 passed, 6 failed
Ora eseguilo una volta con due tentativi aggiuntivi:
npx playwright test --retries=2
Playwright termina con un test in ciascun gruppo. Il test instabile è fallito al primo tentativo ed è riuscito al tentativo aggiuntivo #1. Il vero difetto ha causato il fallimento di tutti e tre i tentativi.
1 failed
bug-or-flaky.spec.js:10:1 › real bug: wrong heading
1 flaky
bug-or-flaky.spec.js:4:1 › flaky: a slow load now and then
Se un nuovo tentativo riesce, significa che l'applicazione funziona bene?
No. Un nuovo tentativo riuscito indica soltanto che i tentativi hanno dato esiti diversi. Se l'esecuzione diventa verde e nessuno controlla, un difetto intermittente nell'applicazione, come una condizione di competizione, dati condivisi o una dipendenza lenta, diventa invisibile, e questi sono tra i difetti più costosi da individuare. Considera un risultato instabile come una segnalazione, non come un successo da ignorare, e non dare per scontato che il problema sia nel test.
Come gestisce Nexus Studio ciascun risultato?
Nexus Studio registra ogni tentativo e assegna al risultato un verdetto specifico, così un nuovo tentativo non trasforma mai un difetto in una semplice esecuzione verde.
- FLAKY: il test è fallito, poi un nuovo tentativo è riuscito, senza che nulla sia stato corretto. Restituisce il codice di uscita 0, quindi la compilazione non si interrompe, e il rapporto e la cronologia segnalano la riserva sull'esito.
- BREACHED: il test è fallito in un unico tentativo e nessuno schema riconducibile all'ambiente o all'infrastruttura di test spiega l'errore. Restituisce il codice di uscita 1.
- BREACHED_FLAKY: il test è fallito all'ultimo tentativo dopo un precedente tentativo aggiuntivo e nessuno schema riconducibile all'ambiente lo spiega. Restituisce il codice di uscita 1. Confronta i tentativi prima di segnalare un difetto.
La cronologia conserva una riga per ogni esecuzione di ciascun test, così un test che diventa verde, rosso e di nuovo verde emerge come andamento anziché scomparire nelle riesecuzioni. La guida ai test instabili elenca i file prodotti da ciascun verdetto.
Quali sono i limiti?
- L'instabilità nell'esempio è simulata con l'aritmetica per renderla ripetibile. L'instabilità reale ha una causa, e trovarla resta un compito per una persona.
- Sei esecuzioni sono un controllo rapido, non un'analisi statistica. Un test con un errore che si verifica una volta ogni cinquanta esecuzioni può riuscire sei volte.
- Un errore a ogni esecuzione non è sempre un difetto dell'applicazione: anche una rete lenta, una pagina di blocco o un browser che non risponde fanno fallire i test. La guida ai falsi fallimenti spiega come distinguerli.
- Con i nuovi tentativi disattivati, un errore intermittente in Nexus Studio viene classificato come BREACHED, perché solo un nuovo tentativo permette di distinguere FLAKY da un semplice errore. La classificazione si basa sul testo dell'errore, quindi apri metadata.json quando un verdetto ti sorprende.
Dove posso vederlo?
La guida ai verdetti spiega in quale ordine il motore determina tutti e 14 i verdetti, mentre la pagina delle evidenze segue un test non riuscito attraverso tutti i file che produce. La versione di prova di 30 giorni esegue lo stesso motore sui tuoi test.