Test di carico e test di stress: differenze, metriche ed esempi k6

  1. Home
  2. Blog
  3. Test del software

Test del software

Test di carico e test di stress: Differenze, metriche ed esempi k6

Uno dimostra che il tuo sistema gestisce il traffico che ti aspetti. L’altro scopre dove si rompe e come si riprende. Scopri quando eseguirli, di quali numeri fidarti e come pianificare un test che dia risposte reali.

9 min di lettura
Test di carico e test di stress: differenze, metriche ed esempi k6

Punti chiave

  • Il test di carico verifica che un sistema raggiunga i suoi obiettivi in condizioni di traffico previsto.
  • Gli stress test spingono oltre la capacità di trovare il punto di rottura e studiare la ripresa.
  • Gli strumenti sono solitamente gli stessi. Ciò che differisce è l’obiettivo e il modello di traffico.
  • Giudica i risultati con percentili come p95 e p99, poiché le medie possono nascondere seri problemi.

La tua applicazione funziona perfettamente con dieci utenti. Cosa succede il giorno dei saldi, con diecimila? Test di carico e test di stress descrivono due diversi modi per rispondere e mescolarli porta a test che non dimostrano ciò che pensi che facciano.

Questa guida spiega cosa mostra ciascuno, i relativi tipi di test e come leggere i risultati. Abbiamo eseguito il calcolo del piccolo percentile riportato di seguito su Python 3.13, con numeri simulati. Gli script k6 sono esempi illustrativi che non abbiamo eseguito e i conteggi degli utenti e gli obiettivi sono inventati, quindi sostituiscili con i tuoi. Esegui questi test solo su sistemi di tua proprietà o che sei autorizzato a testare, poiché il traffico intenso può sembrare un attacco e causare interruzioni reali.

La risposta breve

Un test di carico chiede: possiamo gestire il traffico che ci aspettiamo e raggiungere i nostri obiettivi mentre lo facciamo? Uno stress test chiede: quanto possiamo sopportare prima di fallire, come falliamo e quanto velocemente ci riprendiamo?

Pensa a un ponte. Un test di carico fa attraversare il numero previsto di camion e conferma che va bene. Uno stress test continua ad aggiungere peso per conoscere il suo limite e se dà prima un avvertimento. Fortunatamente, è più economico rompere un software che un ponte.

Test di carico e test di stress fianco a fianco

Aspetto Test di carico Prove di stress
Domanda principale Raggiungiamo gli obiettivi con il carico previsto? Dove e come ci rompiamo?
Livello di traffico Da normale al picco previsto Oltre il picco previsto
Modello Sali, mantieniti costante Continua ad aumentare fino al fallimento
Fallimento Un test fallito Il risultato atteso
Metriche chiave Tempo di risposta, throughput, errori Punto di rottura, modalità di fallimento, tempo di recupero
Tempistica tipica Prima di ogni uscita o evento importante Dopo che il sistema è stabile sotto carico
Risultato Passare o fallire contro gli obiettivi Un limite di capacità e un elenco di punti deboli

Cos’è il test di carico?

Il test di carico simula il traffico realistico previsto e misura il comportamento del sistema. Ha bisogno di un obiettivo rispetto al quale effettuare il test, ad esempio: “con 500 utenti simultanei, il 95% delle richieste di pagamento termina entro 800 ms, con errori inferiori all’1%”.

Ecco come potrebbe apparire come uno script k6. I test k6 sono scritti in JavaScript e thresholds trasformano i tuoi obiettivi in un risultato superato o fallito:

import http from "k6/http";
import { sleep } from "k6";

export const options = {
  stages: [
    { duration: "5m", target: 500 },   // ramp up
    { duration: "20m", target: 500 },  // hold at expected peak
    { duration: "2m", target: 0 },     // ramp down
  ],
  thresholds: {
    http_req_duration: ["p(95)<800"],
    http_req_failed: ["rate<0.01"],
  },
};

export default function () {
  http.get("https://staging.example.com/products");
  sleep(1);   // think time, as real users pause
}

Il sleep conta. Senza tempo per pensare, ogni utente virtuale martella continuamente il server, producendo molto più traffico di quanto farebbe lo stesso numero di persone reali.

Cos’è lo stress test?

Gli stress test vanno deliberatamente oltre i livelli attesi. Non stai cercando di passare. Vuoi risposte a domande come:

  • A quale livello le prestazioni iniziano a crollare?
  • Quale componente si guasta per primo: il database, i server delle applicazioni o una chiamata di terze parti?
  • Fallisce correttamente con errori evidenti o si blocca e perde dati?
  • Si riprende da solo quando il traffico diminuisce?
export const options = {
  stages: [
    { duration: "5m", target: 500 },    // expected peak
    { duration: "5m", target: 1000 },   // beyond it
    { duration: "5m", target: 2000 },   // further
    { duration: "5m", target: 4000 },   // likely to break
    { duration: "10m", target: 0 },     // recovery: does it come back?
  ],
};

La fase finale del recupero viene spesso dimenticata e potrebbe essere quella più preziosa. Un sistema che gestisce bene i guasti ma non si ripristina mai senza un riavvio manuale significa comunque un’interruzione che qualcuno deve riparare nel cuore della notte. Idealmente, in condizioni di carico estremo, un sistema dovrebbe ridurre il lavoro in modo controllato, restituendo chiare 503 risposte invece di andare in timeout.

Spike, ammollo e altri tipi

I test di carico e di stress appartengono a una famiglia più ampia di test delle prestazioni:

Digitare Modello Cosa trova
Fumo (prestazione) Alcuni utenti, brevemente Se la sceneggiatura e il sistema funzionano
Caricare Picco previsto, mantenuto Se gli obiettivi vengono raggiunti
Stress In aumento oltre la capacità Limiti e modalità di fallimento
Spike Un salto improvviso, poi una caduta Scalabilità automatica e comportamento della coda
Ammollo (resistenza) Carico normale per ore Perdite di memoria, connessioni che si esauriscono
Capacità Aumento graduale Il carico massimo entro i tuoi obiettivi

I test di assorbimento rilevano problemi che i test brevi non vedono mai. Una piccola perdita di memoria può sembrare innocua per venti minuti e interrompere il servizio solo dopo due giorni. I test di picco sono adatti a eventi come le vendite flash, in cui il traffico non aumenta gradualmente.

Metriche che contano

Metrico Significato Attenzione
Tempo di risposta (percentili) Quanto tempo impiegano le richieste p95 e p99 in aumento
Produttività Richieste gestite al secondo Appiattimento man mano che gli utenti aumentano
Tasso di errore Percentuale di richieste non riuscite Qualsiasi aumento improvviso
CPU e memoria Utilizzo delle risorse del server Saturazione o crescita costante
Banca dati Query lente, utilizzo del pool di connessioni Esaurimento della piscina, attesa della serratura
Profondità della coda Lavoro in attesa di essere elaborato Crescita che non si esaurisce mai

Perché le medie ingannano

Le medie nascondono le richieste lente di cui le persone reali si lamentano. Per dimostrarlo, abbiamo generato 100 tempi di risposta simulati, di cui 95 rapidi (da 80 a 200 ms) e 5 molto lenti (da 2,5 a 4 secondi), quindi abbiamo calcolato le statistiche comuni:

import math, random, statistics

random.seed(3)
times = [random.randint(80, 200) for _ in range(95)] \
      + [random.randint(2500, 4000) for _ in range(5)]

def pct(values, p):
    values = sorted(values)
    return values[math.ceil(p / 100 * len(values)) - 1]

print("avg", round(statistics.mean(times)), "p50", pct(times, 50),
      "p95", pct(times, 95), "p99", pct(times, 99), "max", max(times))

# avg 302 p50 150 p95 199 p99 3740 max 3896

Osserva attentamente quei numeri. La media di 302 ms non descrive nessuno. Le richieste tipiche impiegavano circa 150 ms, mentre quelle lente impiegavano più di 3 secondi. Anche p95 sembra in buone condizioni con 199 ms, e solo p99 rivela il problema. Una cifra come p95 significa che il 95% delle richieste erano così veloci o più veloci.

E l’1% delle richieste non è un evento raro. Se una pagina effettua 50 richieste, un p99 lento influisce su un’ampia percentuale di visualizzazioni di pagina. Stabilisci obiettivi sui percentili che ti interessano e esaminane diversi insieme.

Suggerimento: Cerca il “ginocchio” nei tuoi grafici. All’aumentare del carico, i tempi di risposta rimangono stabili per un po’, poi aumentano improvvisamente, mentre la produttività smette di crescere. Quel punto è la tua capacità pratica, e spesso arriva ben prima che qualcosa vada effettivamente in crash.

Strumenti

Strumento Scrittura Conosciuto per
k6 JavaScript Le soglie, facili per gli sviluppatori, sono adatte alla CI
JMeter GUI e XML Maturo, supporta molti protocolli
Gatling Scala, Java, Kotlin e altri Basato su codice, efficiente
Locusta Pitone Comportamento utente semplice e basato su Python

Ognuno di questi può eseguire sia test di carico che di stress. Scegli quello che si adatta alle competenze del tuo team, piuttosto che rincorrere un elenco di funzionalità. Per utilizzarne uno nella tua pipeline, vedi cos’è CI/CD.

Come pianificare un test

  1. Fissa obiettivi. Utilizza analisi reali per trovare il traffico di punta e definire obiettivi.
  2. Scegli i viaggi. Modella il comportamento realistico degli utenti, come navigazione, ricerca e pagamento, in proporzioni realistiche. Colpire solo la home page dimostra poco.
  3. Utilizza un ambiente realistico. Un piccolo server di staging non può prevedere la produzione. Nota eventuali differenze.
  4. Prepara i dati. Utilizza volumi realistici, perché una query veloce su 100 righe può eseguire la scansione su 10 milioni.
  5. Avvisa le persone. Informa il tuo team operativo e eventuali terze parti e non caricare per sbaglio il test di un fornitore di servizi di pagamento. Derisione di servizi esterni ove appropriato.
  6. Inizia in piccolo. Esegui prima un piccolo test del fumo per confermare che lo script funziona.
  7. Monitora tutto. Senza le metriche del server, vedrai che è rallentato, ma non il perché.
  8. Ripeti. Eseguilo di nuovo dopo ogni correzione e mantieni una base di riferimento con cui confrontarla.

Leggere i risultati

Sintomo Possibile causa
Risposte lente, ma CPU bassa In attesa di un database, un blocco o un servizio esterno
La CPU del database è elevata Indici mancanti o query inefficienti
Errori di connessione improvvisi Pool di connessioni o limite di file raggiunto
La memoria aumenta costantemente Una perdita o una cache illimitata
Il carico della CPU del generatore è elevato Lo strumento di test è il collo di bottiglia, non il tuo sistema

I database rappresentano un collo di bottiglia comune, quindi se il problema sono le query, leggi la nostra guida all’ottimizzazione delle query SQL. L’ultima riga della tabella è una trappola importante: controlla sempre anche lo stato della macchina che genera il carico.

Errori comuni

  • Confondere gli utenti con le richieste. Sii chiaro se un target indica utenti simultanei o richieste al secondo.
  • Tralasciare il tempo per pensare. Ciò aumenta il traffico e fornisce risultati fuorvianti.
  • Test troppo tardi. Una settimana prima del lancio non lascia tempo per risolvere i problemi di architettura.
  • Utilizzo di un singolo endpoint. Il traffico reale combina letture, scritture e ricerche.
  • La memorizzazione nella cache nasconde tutto. Richieste identiche ripetute possono solo testare la cache, quindi varia i dati.
  • Testare una volta. Le prestazioni cambiano con ogni versione, quindi esegui i test regolarmente.

Considerazioni finali

Esegui test di carico per confermare che sei in grado di gestire il traffico previsto e test di stress per scoprire cosa succede quando non puoi. Inizia in piccolo: scegli il percorso utente più importante, stabilisci un obiettivo chiaro ed esegui un breve test rispetto alla fase di staging con il monitoraggio attivo. Quella prima esecuzione di solito ti insegna qualcosa e puoi costruire da lì.

Domande frequenti

Qual è la differenza principale tra test di carico e stress test?

Il test di carico controlla il comportamento in condizioni di traffico previsto rispetto agli obiettivi impostati. Gli stress test vanno oltre la capacità di individuare il punto di rottura e il modo in cui il sistema si riprende.

Dovrei eseguire prima il test di carico o lo stress test?

Caricare prima il test. Una volta che il sistema raggiunge i suoi obiettivi in ​​condizioni di traffico previsto, esegui stress test per esplorarne i limiti. I risultati dello stress significano poco su un sistema instabile.

Qual è la differenza tra uno stress test e uno spike test?

Uno stress test in genere aumenta il carico passo dopo passo fino al fallimento. Un test di picco passa improvvisamente a un livello elevato, per vedere come il sistema affronta i cambiamenti improvvisi.

Qual è il tempo di risposta p95?

Ciò significa che il 95% delle richieste è stato completato entro tale orario. Descrive l’esperienza della maggior parte degli utenti meglio della media.

Posso eseguire test di carico sulla produzione?

Puoi, ma con attenzione, con il permesso, il monitoraggio e un modo per fermarti rapidamente. La maggior parte dei team inizia con un ambiente di gestione temporanea simile alla produzione per ridurre il rischio per gli utenti reali.

Continua a imparare

Lavora con Stack Quora

Hai bisogno di aiuto con test, WordPress o SEO?

Aiutiamo i team a fornire software migliore e a far crescere i loro siti. Raccontaci a cosa stai lavorando e ti suggeriremo chiaramente il prossimo passo.

Continua a leggere

Altre guide su test, intelligenza artificiale e sviluppo moderno

Ti è piaciuto questo articolo? Scegli un argomento e passa direttamente ai nostri tutorial più recenti.

Intelligenza artificiale

Spiegazione delle allucinazioni dell'intelligenza artificiale: perché i modelli linguistici inventano le cose e come ridurle

Spiegazione delle allucinazioni dell'intelligenza artificiale: cosa sono, perché i modelli linguistici le producono, tipi comuni, come ridurle con b…

Leggi l'articolo →
DevOps

Spiegazione delle variabili d'ambiente: file .env, segreti e configurazione eseguiti correttamente

Variabili d'ambiente spiegate con esempi Python che abbiamo eseguito: lettura e impostazione, perché ogni valore è una stringa, file .env, ereditari…

Leggi l'articolo →
Sviluppo software

Spiegazione della limitazione della velocità API: algoritmi, intestazioni e gestione degli errori 429

La limitazione della velocità dell'API spiegata con una simulazione che abbiamo eseguito: bucket di token, finestra fissa, finestra scorrevole, risp…

Leggi l'articolo →
Automazione dei test

Derisione in Python: unittest.mock, patch e gli errori che fanno mentire i test

Mocking in Python con unittest.mock, testato: Mock e return_value, side_effect, patch dove viene utilizzato un nome, specifiche e autospec, date moc…

Leggi l'articolo →
Test del software

Spiegazione della copertura del codice: copertura di linea o di filiale e cosa significa realmente il 100%.

Copertura del codice spiegata con una vera esecuzione di cover.py: copertura di linea, ramo e condizione, lettura di un rapporto, perché la copertur…

Leggi l'articolo →
Database e SQL

DELETE vs TRUNCATE vs DROP in SQL: differenze, rollback e quando utilizzarli

DELETE vs TRUNCATE vs DROP spiegato con SQL testato: cosa rimuove, rollback, trigger, reimpostazione dell'identità, velocità e come differiscono Pos…

Leggi l'articolo →
Database e SQL

Spiegazione delle visualizzazioni SQL: crea, utilizza ed evita le insidie, con esempi

Viste SQL spiegate con le query che abbiamo eseguito: creazione di una vista, risultati in tempo reale, nascondere colonne, prestazioni, viste aggio…

Leggi l'articolo →
Sviluppo software

Interfaccia TypeScript e tipo: differenze reali, testate con il compilatore

Interfaccia TypeScript vs tipo, verificata con il vero compilatore: cosa possono fare entrambi, cosa può fare solo uno, fusione delle dichiarazioni,…

Leggi l'articolo →
Sviluppo software

Spiegazione di Python *args e **kwargs: funzioni flessibili con esempi chiari

Python *args e **kwargs spiegati con il codice che abbiamo eseguito: compressione e decompressione, ordine dei parametri, argomenti solo per parole …

Leggi l'articolo →
Sviluppo software

Funzioni Lambda Python: sintassi, usi reali e quando non usarli

Funzioni lambda Python spiegate con il codice che abbiamo eseguito: sintassi, ordinamento con chiave, mappa e filtro, chiusure, trap dell'associazio…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli agenti AI? Come funzionano, con un semplice ciclo di agenti che puoi eseguire

Cosa sono gli agenti IA? Una semplice guida al ciclo dell'agente, agli strumenti, alla memoria e ai guardrail, con un piccolo ciclo Python che abbia…

Leggi l'articolo →
DevOps

Monitoraggio vs osservabilità: la vera differenza, con log, metriche e tracce

Spiegazione del monitoraggio e dell'osservabilità: errori noti e sconosciuti, log, metriche e tracce, una procedura dettagliata sugli incidenti di p…

Leggi l'articolo →
DevOps

Volumi Docker e montaggi di associazione: mantenere i dati del contenitore nel modo giusto

Volumi Docker e montaggi di collegamento spiegati: perché i dati del contenitore scompaiono, volumi denominati, montaggi di collegamento, tmpfs, ese…

Leggi l'articolo →
Automazione dei test

TDD vs BDD: differenze chiave, una caratteristica costruita in entrambi i modi e quando utilizzarli ciascuno

TDD vs BDD spiegato con una funzione di sconto costruita in entrambi i modi: refactoring rosso-verde con il codice che abbiamo eseguito, scenari "Da…

Leggi l'articolo →
Test del software

Test di accettazione da parte dell'utente (UAT): processo, lista di controllo ed esempi reali

Spiegazione del test di accettazione dell'utente: chi lo esegue, in cosa differisce dal QA, un processo in sette fasi, un modello di test case UAT, …

Leggi l'articolo →
Database e SQL

Spiegazione dei valori SQL NULL: IS NULL, COALESCE, NULLIF e le trappole da evitare

Valori SQL NULL spiegati con le query che abbiamo eseguito: logica a tre valori, IS NULL, COALESCE, NULLIF, come aggregazioni, join e ordinamento tr…

Leggi l'articolo →
Database e SQL

Istruzione SQL CASE WHEN: sintassi, esempi reali ed errori comuni

SQL CASE WHEN spiegato con le query che abbiamo eseguito: moduli semplici e cercati, ordine delle condizioni, pivot con SUM, trucchi COUNT, ordiname…

Leggi l'articolo →
Sviluppo software

Cos'è il JWT? Token Web JSON spiegati con un esempio funzionante

Cos'è il JWT? Spiegazione dei token Web JSON: le tre parti, un token creato e manomesso nel codice che abbiamo eseguito, JWT e sessioni, archiviazio…

Leggi l'articolo →
Sviluppo software

Spiegazione del loop di eventi JavaScript: stack di chiamate, microtask e timer con esempi

Il ciclo di eventi JavaScript spiegato con il codice che abbiamo eseguito: stack di chiamate, code di attività e microtask, perché setTimeout 0 non …

Leggi l'articolo →
Sviluppo software

Spiegazione dei generatori Python e del rendimento: risparmia memoria con esempi reali

Generatori Python e rendimento spiegati con il codice che abbiamo eseguito: come vengono messi in pausa e ripresi, misurato il risparmio di memoria,…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli incorporamenti? I vettori e la somiglianza del coseno spiegati semplicemente

Cosa sono gli incorporamenti? Una guida in linguaggio semplice ai vettori, alla similarità del coseno e alla ricerca semantica, con un piccolo esemp…

Leggi l'articolo →
DevOps

Distribuzione blu-verde rispetto a quella canaria: differenze, compromessi e come scegliere

Spiegazione della distribuzione blu-verde e canary: come funziona ciascuna, costi, rischi e rollback, bucket utente stabile che abbiamo testato, mig…

Leggi l'articolo →
Automazione dei test

Test instabili: quali sono le cause e come risolverli definitivamente

Test instabili spiegati con demo che abbiamo eseguito: le cause principali, come confermarne e diagnosticarne uno, soluzioni adeguate per tempistich…

Leggi l'articolo →
Test del software

Test di carico e test di stress: differenze, metriche ed esempi k6

Spiegazione del test di carico e dello stress test: cosa dimostra ciascuno, test di picco e di assorbimento, le metriche che contano, perché le medi…

Leggi l'articolo →
Test del software

Caso di test e scenario di test: differenze chiave, esempi e quando utilizzarli

Spiegazione del caso di test e dello scenario di test: definizioni chiare, una tabella affiancata, una funzione di reimpostazione della password pre…

Leggi l'articolo →
Database e SQL

Ottimizzazione delle query SQL: leggi i piani di esecuzione e correggi query lente, con tempistiche

Ottimizzazione delle query SQL testata su un milione di righe: leggi i piani di esecuzione, aggiungi gli indici corretti, correggi filtri non aggior…

Leggi l'articolo →
Database e SQL

SQL UNION vs UNION ALL: differenze, esempi e prestazioni testate

SQL UNION vs UNION ALL spiegati con le query che abbiamo eseguito: duplicati, regole seguite da entrambi, un vero bug di dati, prestazioni misurate,…

Leggi l'articolo →
Sviluppo software

Tutorial sull'API di recupero JavaScript: GET, POST, gestione degli errori e timeout

Un tutorial sull'API JavaScript Fetch testato su un server locale: GET e POST, perché 404 non genera eccezioni, un helper riutilizzabile, stringhe d…

Leggi l'articolo →
Sviluppo software

Gestione dei file Python: lettura, scrittura, CSV, JSON e pathlib con esempi

Gestione dei file Python spiegata con il codice che abbiamo eseguito: modalità aperte, con, lettura di file di grandi dimensioni, CSV, JSON, pathlib…

Leggi l'articolo →
Sviluppo software

Git merge vs rebase: differenze, esempi e quando usare ciascuno

Git merge vs rebase spiegato con output reale del log, una tabella di confronto, la regola d'oro del rebase e un flusso di lavoro sicuro per i team.

Leggi l'articolo →
Sviluppo software

List comprehension in Python: sintassi, esempi e quando evitarla

List comprehension in Python spiegata: sintassi, filtri, if-else, cicli annidati, tempi misurati e i casi in cui un normale ciclo for è meglio.

Leggi l'articolo →
Database e SQL

SQL JOIN spiegati con esempi (Inner, Left, Right, Full)

Capisci i JOIN SQL passo dopo passo con tabelle e query di esempio: INNER, LEFT, RIGHT, FULL, CROSS e SELF, con errori comuni e consigli sulle prest…

Leggi l'articolo →