Cosa impari
- Perche gli agenti rendono i test piu importanti, non meno, e il quality gate a quattro strati
- Scrivere test unitari Vitest e test end-to-end Playwright che sopravvivono ai refactor
- Far girare tutta la suite automaticamente con un pre-push hook e GitHub Actions
Panoramica
C'e il mito che l'IA scrive il codice, quindi non hai piu bisogno di test. E vero il contrario. Un agente riscrive allegramente una funzione che funzionava alle 2 di notte perche hai chiesto un cambiamento senza relazione, e non ha nessun ricordo di perche il vecchio comportamento contava. I test sono il modo in cui dici ai futuri agenti cosa non deve rompersi. Questa lezione costruisce il quality gate a quattro strati - tipi, lint, unitari, end-to-end - e lo cabla in un pre-push hook e una pipeline CI, perche la qualita sia imposta dalla macchina, non dalla tua disciplina.
Cosa imparerai
Imparerai cosa coglie ogni strato dello stack qualita, come scrivere un test unitario Vitest e un test end-to-end Playwright che continuano a funzionare dopo un refactor, come bloccare un push cattivo con un git hook e come far girare tutta la suite automaticamente a ogni push con GitHub Actions. Alla fine, puoi dare a un agente mano libera in un repo e fidarti del gate per cogliere i suoi errori.
Prerequisiti
Un progetto TypeScript funzionante dai corsi precedenti e la lezione sugli hook del Corso 2, perche CI/CD e solo la versione a livello di squadra di un gate pre-push. Non hai bisogno di essere esperto di test. L'obiettivo di questa lezione e fare dei test un'abitudine che il tuo agente fa per te, non una disciplina che devi ricordare.
Il problema
Quando fai girare un agente duro, tocca molto codice in fretta. Un cambiamento in un file rompe in silenzio un altro. L'agente segnala un successo, perche il file che ha modificato sembra corretto, e scopri la regressione solo quando una pagina e vuota in produzione. Il test manuale non scala al ritmo di un agente - non puoi cliccare attraverso ogni flusso dopo ogni cambiamento. Senza gate automatico, ogni sessione d'agente e una piccola scommessa sul tuo prodotto live. La soluzione e fare di "funziona ancora?" una domanda a cui la macchina risponde in secondi.
Il quality gate a quattro strati
Ogni strato coglie una classe diversa di bug, e diventano piu lenti e piu approfonditi man mano che scendi. Fai girare i rapidi di continuo e i lenti prima della pubblicazione. Insieme, formano una rete abbastanza serrata perche i cambiamenti rapidi, pilotati da agente, restino sicuri.
- Type check (tsc --noEmit): coglie gli errori di forma - una funzione chiamata con gli argomenti sbagliati, una proprieta che non esiste, un null che hai dimenticato di gestire. Istantaneo e gratuito.
- Lint (ESLint): coglie i pattern soggetti a errori e la deriva di stile - variabili inutilizzate, await mancanti, console.log accidentali. Tiene il codice scritto dall'agente coerente con il tuo.
- Test unitari (Vitest): verificano che la tua logica sia effettivamente corretta - un calcolo di prezzo, una regola di validazione, un formattatore di data. Rapidi, da far girare a ogni salvataggio.
- Test end-to-end (Playwright): pilotano un vero browser attraverso interi percorsi utente - connettersi, mettere nel carrello, checkout. Lenti, ma provano che la vera cosa funziona.
Scrivere un test unitario Vitest
I test unitari sono piccoli e rapidi. Dai un input a una funzione e verifichi l'output. Il trucco che li fa sopravvivere ai refactor d'agente: testa il comportamento, non l'implementazione. Verifica cio che la funzione deve produrre per un utente, mai i passi privati che percorre per arrivarci. Allora l'agente puo riscrivere le interne liberamente e il test tiene comunque il contratto.
import { describe, it, expect } from 'vitest'
import { yearlyPricePerMonth } from './pricing'
describe('yearlyPricePerMonth', () => {
it('shows the discounted monthly figure for a yearly plan', () => {
// Monthly is 17% above yearly, so yearly-per-month is monthly / 1.17.
expect(yearlyPricePerMonth({ monthly: 117 })).toBe(100)
})
it('never returns a negative price', () => {
expect(yearlyPricePerMonth({ monthly: 0 })).toBeGreaterThanOrEqual(0)
})
})Quando chiedi a un agente di aggiungere una feature, aggiungi una riga al tuo spec: "scrivi un test Vitest per questo". Ora l'agente lascia un filo-trappola che protegge la feature dal prossimo agente, inclusa una futura versione di se stesso.
Scrivere un test end-to-end Playwright
Playwright lancia un vero browser, visita la tua app e clicca come un utente. Coglie i bug che i test unitari non possono: una route rotta, un pulsante che non fa niente, un form che non si invia mai. Scrivi i test end-to-end prima per i tuoi cammini di denaro - il pugno di flussi dove una rottura ti costa un cliente. Scegli gli elementi per cio che l'utente vede, o per test ID stabili, mai per CSS fragile, perche un redesign non rompa ogni test.
import { test, expect } from '@playwright/test'
test('a visitor can reach the pricing page from the hero CTA', async ({
page,
}) => {
await page.goto('/')
await page.getByRole('link', { name: 'See pricing' }).click()
await expect(page).toHaveURL(/\/pricing/)
await expect(
page.getByRole('heading', { name: 'Pricing' }),
).toBeVisible()
})Il pre-push hook: il tuo gate locale
Il primo posto per imporre il gate e la tua macchina, nell'istante prima che il codice la lasci. Un git pre-push hook fa girare le tue verifiche e rifiuta il push se una fallisce, perche il codice rotto non raggiunga mai il repo. E la stessa idea che hai incontrato nel Corso 2, ora diretta sulla suite completa. Tieni l'hook locale rapido - tipi, lint e test unitari - e lascia la suite end-to-end piu lenta girare in CI.
#!/usr/bin/env sh
# .husky/pre-push - blocca il push se una verifica fallisce
bun run typecheck || exit 1
bun run lint || exit 1
bun run test || exit 1
echo "All checks passed - pushing."Un hook che puoi saltare con --no-verify e un suggerimento, non un gate. L'hook e il tuo feedback rapido; la CI e il gate che nessuno puo aggirare. Vuoi entrambi.
GitHub Actions: il gate che nessuno puo saltare
L'integrazione continua fa girare tutta la tua suite sui server di GitHub a ogni push e pull request, non importa cosa qualcuno ha fatto girare localmente. Un file di workflow in .github/workflows dice a GitHub cosa fare. L'esempio qui sotto installa le dipendenze poi fa girare i quattro strati, inclusi i test end-to-end. Regola il tuo branch perche questa verifica debba passare prima di ogni merge, e una regressione semplicemente non puo raggiungere il tuo branch main.
name: Quality gate
on:
push:
branches: [main]
pull_request:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run typecheck
- run: bun run lint
- run: bun run test
- run: bunx playwright install --with-deps
- run: bun run test:e2eErrori frequenti
I grossi: scrivere zero test perche "l'agente l'ha gia verificato" (non puo vedere la tua app live); testare dettagli di implementazione, cosicche ogni refactor mette la suite al rosso e cominci a ignorarla; rendere l'hook locale cosi lento che lo aggiri con --no-verify; e avere la CI ma non esigere che passi prima del merge, cosicche diventa decorativa. Testa il comportamento, tieni il gate locale rapido e rendi la CI obbligatoria.
ROI business
Una regressione che raggiunge un cliente ti costa la fiducia, un ticket di supporto e un fix d'emergenza, spesso al peggiore momento immaginabile. Un test che la coglie costa i pochi secondi che impiega a girare. Una volta che il gate e in atto, puoi lasciare gli agenti lavorare molto piu aggressivamente, perche il costo di un errore passa da "ha rotto la produzione" a "la pipeline e passata al rosso, correggi prima del merge". E la vera liberazione: i test non sono un overhead sul development agentico, sono cio che rende sicuro il development agentico aggressivo.
Checklist
Sei pronto ad andare avanti quando ognuno di questi punti e vero per un vero progetto, non solo in teoria.
- Sai spiegare cosa coglie ognuno dei quattro strati che gli altri mancano.
- Almeno un test Vitest e un test Playwright passano nel tuo progetto.
- Un pre-push hook fa girare gli strati rapidi e blocca un push fallito.
- Un workflow GitHub Actions fa girare la suite completa ed e richiesto prima del merge.
Risorse
Tieni nei preferiti la documentazione ufficiale Vitest e Playwright per i matcher e i selettori e la documentazione GitHub Actions per la sintassi di workflow, perche evolvono. Aggiungi "scrivi un test per questo" ai tuoi vincoli di spec-sheet standard, perche ogni compito d'agente lasci un filo-trappola. La lezione sugli hook del Corso 2 vale una rilettura, ora che cabli la suite completa.
La tua missione
Aggiungi un test Vitest e un test Playwright a un vero progetto, poi aggiungi il pre-push hook e il workflow GitHub Actions qui sopra. Rompi deliberatamente qualcosa che un agente potrebbe rompere - rinomina una route, cambia l'output di una funzione - e conferma che il gate passa al rosso. Questo rosso e tutto il punto: ha colto l'errore prima che lo facesse un utente.
Prossima lezione
Coperta la qualita, la prossima lezione indurisce la sicurezza: rate limit su ogni endpoint pubblico, header CSP, cifrare le credential memorizzate e l'audit pre-pubblico che impedisce a un segreto di trapelare quando passi un repo in pubblico.

Commenti
Caricamento dei commenti.
Pubblica un commento