La migrazione dei test Angular a Vitest si blocca prima della prima asserzione
Testo scritto con l’intelligenza artificiale a partire da una fonte citata, senza revisione umana prima della pubblicazione.
Errori di import, configurazione TypeScript e API mancanti in jsdom possono fermare l'esecuzione dei test e nascondere i veri guasti dei componenti
Primo run dopo il passaggio da Karma a Vitest: oltre mille errori TypeScript, zero test eseguiti1. Sotto Karma, gli stessi test passavano in Chrome. Con Angular 21, i nuovi progetti usano Vitest per default e, se non richiesto, girano in jsdom, un DOM simulato1.
Autore: Müslüm Yılmaz, creatore di FrontendAtlas1.
Tipo: tsconfig
La guida non cita i tipi. In tsconfig.spec.json restavano quelli di Jasmine. Sostituirli con "vitest/globals" ha eliminato la maggior parte degli errori e sbloccato la compilazione1.
I file con errori di tipo nei mock sono stati esclusi. I test con fakeAsync sono rimasti, ancora rossi. La guida indica una patch di zone.js e suggerisce la riscrittura verso i fake timers di Vitest. Richiedono fix separati, quindi l’esclusione ha riguardato anche tsconfig.spec.json, non solo angular.json, per evitare che il type check li ricompilasse1.
Snippet minimo:
- tsconfig.spec.json: sostituire i tipi Jasmine con "vitest/globals"1.
- Escludere gli spec rotti sia in angular.json sia in tsconfig.spec.json1.
Diagnosi: cosa è davvero in test
Una volta compilata, la suite ha avuto 88 fallimenti. Solo 14 sono arrivati a un’asserzione. Molti si sono fermati prima. Di questi, 52 si rompevano per un’API mancante in jsdom. In Chromium passavano senza modifiche1.
Metodo usato: per ogni spec, due domande. È partito almeno un test? Lo stesso spec passa in un browser reale? Ogni file è stato eseguito due volte con Vitest 4, in jsdom e in Chromium1.
Import CommonJS: errori che fermano tutto
Un fixture minimo ha isolato i guasti da import. Il componente PriceTag importava formatPrice per nome da price-format, un pacchetto CommonJS. Node rifiuta quel named export. Con Vitest, deps.interopDefault, attivo per default, fa passare. Disattivandolo, l’errore diventa “TypeError: formatPrice is not a function”, sebbene la causa sia l’import1.
Il deep import price-format/lib/format funziona con la 1.0.0. La 1.1.0 aggiunge una exports map che espone solo la root. Dopo l’upgrade: “TS2307: Cannot find module ‘price-format/lib/format’”. Nessun test parte, in jsdom e in Chromium, perché la build è la stessa. Importare dal root del pacchetto risolve. Per intercettare prima, una regola ESLint segnala i deep import non pubblici1:
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["price-format/*"],
"message": "Import from 'price-format'. Deep paths are not part of its public API."
}]
}]
API assenti in jsdom: matchMedia
window.matchMedia mancava e causava un TypeError in 34 test, su dieci file, tutti alla riga 897 di GuideShell. Ordinare i fallimenti per prima riga dello stack nel proprio codice ha portato subito lì. Il check esistente usava solo isBrowser, ma il setup Angular lo riporta true anche in jsdom. Serviva verificare la presenza della funzione. Aggiungere typeof window.matchMedia !== 'function' ha fatto passare tutti e 34 i test. I fallimenti totali sono scesi da 88 a 541.
Mock robusti: stub, non spy
La conversione delle spie Jasmine in vi.spyOn(window, 'matchMedia') falliva in jsdom: “Received undefined”. Soluzione: vi.stubGlobal per impostare matchMedia in entrambi gli ambienti, con reset in afterEach. Senza reset, un test in Chromium falliva per un mock rimasto attivo1:
afterEach(() => vi.unstubAllGlobals());
it('cade al tema chiaro quando matchMedia manca', async () => {
vi.stubGlobal('matchMedia', undefined);
const fixture = TestBed.createComponent(ThemeBadge);
await fixture.whenStable();
expect(fixture.nativeElement.textContent).toContain('light');
});
Togliendo il typeof nel componente, il test fallisce in jsdom e in Chromium, come atteso da una regressione mirata1.
Chiusura
La lezione operativa: separare gli errori di modulo, di ambiente DOM e i difetti reali. Fixture minime, lint per i deep import e doppio run jsdom, Chromium riducono i falsi allarmi e impediscono che un upgrade blocchi la suite prima della prima asserzione1.
Fonti
Come è nato questo articolo Scritto da un sistema di intelligenza artificiale, con controlli automatici
Millebit non ha giornalisti che scrivono gli articoli: li scrive un motore editoriale basato su modelli di intelligenza artificiale, a partire dalle fonti elencate qui sopra. Prima di uscire, ogni testo passa questi controlli:
- Rilettura. Un passaggio toglie i tic della prosa generata da un modello, come i contrasti costruiti e le frasi che annunciano invece di informare, senza toccare fatti e fonti.
- Fedeltà alle fonti. Un passaggio dedicato toglie ogni affermazione che le fonti non sostengono. Valutazione su questo pezzo: 10/10.
- Anti-cliché. Un filtro scarta frasi fatte, enfasi e tic della prosa artificiale: superato.
- Giudizio editoriale. Un modello valuta il pezzo su sette criteri (apertura, chiarezza, economia, concretezza, voce, struttura, fedeltà) e sotto 7,8/10 non si pubblica. Questo articolo ha preso 8,5/10 dopo 1 revisione.
I controlli riducono gli errori ma non li eliminano: un modello può fraintendere una fonte. Per le decisioni importanti, risali alla fonte originale. Se trovi un errore, segnalacelo.
Per vedere Millebit nelle notizie principali di Google, aggiungilo alle tue fonti preferite. Oppure segui l’edizione di oggi, il feed RSS o La Sintesi.