# Load Testing ASP.NET Core Applicazioni con k6: Introduzione

<!--category-- Testing, Performance, k6, ASP.NET -->
<datetime class="hidden">2025-12-02T14:00</datetime>

La vostra applicazione funziona perfettamente sul vostro computer portatile. Test di unità passano. I test di integrazione passano. Implementate alla produzione, e improvvisamente tutto si arresta. Cinquecento utenti reali hanno colpito la vostra homepage contemporaneamente, e il vostro server inizia a restituire 503 errori. La vostra strategia di caching attentamente artigianale? Scopri che non funziona esattamente come pensavate. La query del database che pensavate fosse veloce? Sta creando un collo di bottiglia in scala.

Questo è lo scenario da incubo che ogni sviluppatore teme, ma la maggior parte non prova per. **Il test delle prestazioni non è facoltativo - è la differenza tra un lancio di successo e una pagina di emergenza 3 AM.** Questa guida in due parti vi mostrerà esattamente come evitare questo scenario utilizzando k6, il moderno strumento di prova del carico che è abbastanza potente per le applicazioni aziendali, ma abbastanza semplice da funzionare nella vostra pipeline CI / CD.

Questo e' **Parte 1** di una serie in due parti su prove di carico con k6:

- **Parte 1 (questo articolo)**: Introduzione a k6, installazione, tipi di test, e perché k6
- **[Parte 2: Attuazione pratica](/blog/k6-testing-practical)**: Test di scrittura, integrazione CI/CD, profilazione ed esempi reali

## Introduzione

Il test delle prestazioni è fondamentale per qualsiasi applicazione ASP.NET Core di produzione. Sia che si stia costruendo un blog semplice, un'architettura complessa di microservizi o un'applicazione aziendale, è necessario sapere come la vostra applicazione si comporta sotto carico. Sarà gestire 100 utenti contemporanei? 1.000? Dove sono le strozzature? La vostra strategia di cacheing funziona davvero?

Questa guida completa mostra come caricare le applicazioni di test ASP.NET Core utilizzando [k6](https://k6.io/) - uno dei più potenti strumenti di test del carico open-source disponibili. [MinimalBlog](/blog/minimalblog-introduction) come la nostra applicazione di esempio (un semplice blog basato su markdown con memoria e output caching), le tecniche e i modelli indicati qui si applicano a **qualsiasi applicazione ASP.NET Core**.

Entro la fine di questa serie in due parti, saprai come:

- Installare e configurare k6 su qualsiasi piattaforma (Windows, Mac, Linux)
- Scrivi test di prestazioni completi per diversi scenari
- Integrare k6 nella pipeline CI/CD con le azioni GitHub
- Utilizzare strumenti di profilazione (dotTrace, dotMemory) insieme a k6 per trovare strozzature
- Implementa diverse strategie di test: fumo, carico, stress, picco e test di immersione
- Impostare il rilevamento della regressione delle prestazioni per evitare che il codice lento raggiunga la produzione

**Perché MinimalBlog come esempio?** Si tratta di una vera e propria applicazione ASP.NET Core 9.0 con modelli comuni: Razor Pages, memory caching, output caching, file I/O, e markdown processing. Gli approcci di test che imparerete si applicano allo stesso modo alle vostre applicazioni MVC, Web API, applicazioni Blazor, o API minime.

[TOC]

## Che cos'è k6 e perché usarlo?

[k6](https://k6.io/) è un moderno strumento di test del carico costruito per gli sviluppatori. A differenza di vecchi strumenti come JMeter o LoadRunner, k6 è:

- **Sviluppatore-friendly**: I test sono scritti in JavaScript (ES6+)
- **CLI-first**: Perfetto per condotte CI/CD
- **Leggero**: Singola binaria, senza dipendenze
- **Precisa**: Scritto in Vai per metriche precise
- **Scriptable**: Complete capacità di programmazione per scenari complessi
- **Cloud-ready**: Può integrarsi con k6 Cloud, Grafana, Prometheus

Per MinimalBlog, k6 è ideale perché:

1. **Possiamo testare il caching**: k6 può verificare le intestazioni della cache e il comportamento
2. **Possiamo simulare il traffico reale**: Provare più utenti simultanei
3. **Possiamo convalidare le richieste di prestazioni**: Misurare i tempi di risposta effettivi
4. **Possiamo integrarci con CI/CD**: Automatizzare i test nella nostra pipeline
5. **Possiamo testare scenari specifici**: Filtraggio di categorie, singoli post, homepage

## Installazione di k6

### Installazione di Windows

**Opzione 1: utilizzo della cioccolata (raccomandata)**

```powershell
choco install k6
```

**Opzione 2: Utilizzo di Winget**

```powershell
winget install k6 --source winget
```

**Opzione 3: Installazione manuale**

1. Scarica l'ultima versione di Windows da [Rilascia GitHub](https://github.com/grafana/k6/releases)
2. Estrae la `k6.exe` file
3. Aggiungi la directory al tuo PATH o sposta `k6.exe` a una directory già in PATH

**Verifica installazione:**

```powershell
k6 version
```

### Installazione Mac

**Opzione 1: utilizzo di homebrew (raccomandato)**

```bash
brew install k6
```

**Opzione 2: utilizzo di MacPorts**

```bash
sudo port install k6
```

**Opzione 3: Installazione manuale**

```bash
# Download and install the latest release
curl -O -L https://github.com/grafana/k6/releases/latest/download/k6-macos-amd64.zip
unzip k6-macos-amd64.zip
sudo cp k6-macos-amd64/k6 /usr/local/bin/
sudo chmod +x /usr/local/bin/k6
```

**Verifica installazione:**

```bash
k6 version
```

### Installazione di Linux

**Opzione 1: Uso dei gestori dei pacchetti**

Per **Debian/Ubuntu**:

```bash
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
```

Per **Fedora/CentOS/RHEL**:

```bash
sudo dnf install https://dl.k6.io/rpm/repo.rpm
sudo dnf install k6
```

**Opzione 2: Uso di Snap**

```bash
sudo snap install k6
```

**Opzione 3: Installazione manuale**

```bash
# Download the latest release
curl -O -L https://github.com/grafana/k6/releases/latest/download/k6-linux-amd64.tar.gz
tar -xzf k6-linux-amd64.tar.gz
sudo cp k6-linux-amd64/k6 /usr/local/bin/
sudo chmod +x /usr/local/bin/k6
```

**Opzione 4: Uso di Docker**

```bash
docker pull grafana/k6:latest

# Run a test
docker run --rm -i grafana/k6:latest run - <script.js
```

**Verifica installazione:**

```bash
k6 version
```

## Comprendere l'anatomia del test k6

Prima di immergerci nel test, capiamo la struttura di base di un test k6:

```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';

// Test configuration
export const options = {
  vus: 10,              // Virtual users
  duration: '30s',      // Test duration
};

// Setup function (runs once before test)
export function setup() {
  // Prepare test data
  return { baseUrl: 'http://localhost:5000' };
}

// Main test function (runs for each VU)
export default function(data) {
  const response = http.get(data.baseUrl);

  // Assertions
  check(response, {
    'status is 200': (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  });

  sleep(1); // Wait between iterations
}

// Teardown function (runs once after test)
export function teardown(data) {
  // Clean up
}
```

Concetti chiave:

- **Utenti virtuali (VU)**: Utenti simulati simultanei
- **Durata**: Per quanto tempo dura il test
- **Controlli**: Asserzioni che non fermano il test
- **Soglia**: Criteri di passaggio/fallimento
- **MetricsCity name (optional, probably does not need a translation)**: Tempo di risposta, throughput, tasso di errore

## Tipi di prove di prestazione

Prima di testare l'applicazione, cerchiamo di capire i cinque principali tipi di test di carico e quando utilizzare ciascuno:

```mermaid
graph TD
    A[Performance Testing Types] --> B[Smoke Test]
    A --> C[Load Test]
    A --> D[Stress Test]
    A --> E[Spike Test]
    A --> F[Soak Test]

    B --> B1[1-2 VUs<br/>30s-1min<br/>Basic Functionality]
    C --> C1[Normal Load<br/>5-15 minutes<br/>Verify SLAs]
    D --> D1[Gradual Increase<br/>10-30 minutes<br/>Find Breaking Point]
    E --> E1[Sudden Spike<br/>5-10 minutes<br/>Test Recovery]
    F --> F1[Normal Load<br/>Hours/Days<br/>Memory Leaks]

    style B stroke:#90EE90
    style C stroke:#87CEEB
    style D stroke:#FFD700
    style E stroke:#FF6347
    style F stroke:#DDA0DD
```

### 1. Prove di fumo

**Oggetto**: Verificare che il sistema funzioni sotto carico minimo

**Quando usare**:

- Dopo ogni cambiamento di codice
- Prima di eseguire prove più intensive
- Come controllo sanitario in CI/CD

**Caratteristiche**:

- 1-2 VU (Utenti virtuali)
- Breve durata (30s-1min)
- Prove di funzionalità di base

### 2. Prove di carico

**Oggetto**: Valutare le prestazioni sotto il carico normale previsto

**Quando usare**:

- Per stabilire le prestazioni di base
- Per verificare che gli SLA siano soddisfatti
- Prova regolare di regressione delle prestazioni

**Caratteristiche**:

- Numero realistico di utilizzatori
- Carico sostenuto
- Durata tipica: 5-15 minuti

### 3. Prove di stress

**Oggetto**: Trova il punto di rottura del sistema

**Quando usare**:

- Comprendere i limiti di capacità
- Individuare le strozzature
- Pianificazione della scalatura

**Caratteristiche**:

- Gradualmente aumentando il carico
- Spingere oltre la capacità normale
- Durata: 10-30 minuti

### 4. Prove Spike

**Oggetto**: Comportamento di prova sotto picchi di traffico improvvisi

**Quando usare**:

- Preparazione al lancio del prodotto
- Prova di autoscaling
- Convalida del comportamento di ripiego

**Caratteristiche**:

- Improvviso grande aumento del carico
- Breve durata del picco
- Durata totale: 5-10 minuti

### 5. Test di ammorbidimento (test di resistenza)

**Oggetto**: Trova perdite di memoria e degrado nel tempo

**Quando usare**:

- Prima delle release principali
- Verifica dei servizi di lunga durata
- Convalida della pulizia delle risorse

**Caratteristiche**:

- Livelli di carico normali
- Durata prolungata (ore o giorni)
- Monitor per la degradazione

```mermaid
graph LR
    A[Start] --> B{Smoke Test Pass?}
    B -->|No| C[Fix Issues]
    C --> A
    B -->|Yes| D{Load Test Pass?}
    D -->|No| E[Optimize]
    E --> D
    D -->|Yes| F{Stress Test}
    F --> G{Found Limit?}
    G -->|Yes| H[Document Capacity]
    G -->|No| I[Increase Load]
    I --> F
    H --> J{Spike Test Pass?}
    J -->|No| K[Improve Resilience]
    K --> J
    J -->|Yes| L{Soak Test}
    L --> M{Memory Stable?}
    M -->|No| N[Fix Memory Leaks]
    N --> L
    M -->|Yes| O[Production Ready]

    style O stroke:#90EE90
```

## Perche' K6 e Not...?

Con così tanti strumenti di test del carico disponibili, perché si dovrebbe scegliere k6? Confrontiamo k6 con le alternative popolari:

### k6 vs Apache JMeter

**Apache JMeter** è il veterano degli strumenti di prova del carico (dal 1999).

|Caratteristiche | k6 | JMeter |
|---------|----|---------|
| **Installazione** | Singola binaria, senza dipendenze | Richiede Java, installazione più pesante |
| **Definizione della prova** | codice JavaScript | XML o GUI |
| **Uso delle risorse** | Peso leggero (Go) | Pesante (Java) |
| **Integrazione CI/CD** |Eccellente (CLI-first) | Richiede plugin |
| **Curve di apprendimento** |Easy for developers | Steeper, GUI-focused |
| **Supporto protocollo** | HTTP, WebSockets, GRPC | Broader (FTP, JDBC, SMTP, ecc.) |

**Quando usare JMeter invece:**

- L'interfaccia grafica necessaria per i tester non tecnici
- Protocolli di prova oltre l'HTTP (JDBC, LDAP, SOAP)
- Hanno già JMeter esperienza in team
- Bisogno di un vasto ecosistema plugin

**Perché k6 è meglio per la maggior parte delle applicazioni ASP.NET Core:**

- Test più veloci da scrivere (JavaScript vs XML)
- Impronta delle risorse più leggera
- Migliore integrazione CI/CD
- Esperienza di sviluppatore più moderna

### k6 vs Locust

**LocustCity name (optional, probably does not need a translation)** è uno strumento di prova del carico basato su Python, popolare nei negozi di Python.

| Caratteristica | k6 | Locusta |
|---------|----|---------|
| **Lingua** | JavaScript | Pitone |
| **Prestazioni** | Very fast (Go runtime) | Slow (Python GIL) |
| **Facilità d'uso** | JavaScript semplice | Pitonico, facile |
| **Test distribuiti** |K6 Cloud (paid) | Built-in (free) |
| **UI web** | Limited | Excellent real-time UI |
| **Esportazione metrica** | Molti formati | CSV, web UI |

**Quando usare Locust invece:**

- Prima squadra di Python
- Bisogno di test gratuiti distribuiti
- Vuoi l'interfaccia utente web in tempo reale durante i test
- Logica Python complessa nelle prove

**Perché k6 è meglio per la maggior parte delle applicazioni ASP.NET Core:**

- Prestazioni migliori per metriche accurate
- JavaScript più familiare per gli sviluppatori web
- Sintassi soglia/assertimento più pulita
- Migliore integrazione Prometheus/Grafana

### k6 vs Gatling

**GatlingCity name (optional, probably does not need a translation)** è uno strumento basato sulla Scala con un eccellente reporting.

|Caratteristiche | k6 |Gatling |
|---------|----|---------|
| **Lingua** | JavaScript | Scala/Java |
| **Relazioni** | Basic (+ extensions) | Beautiful built-in HTML reports |
| **Curve di apprendimento** | Facile | Moderate (Scala DSL) |
| **Prestazioni** |Eccellente |Eccellente |
| **Open Source** | Completamente aperto | Aperto con add-on aziendali |
| **Servizio cloud** |K6 Cloud |Gatling Enterprise |

**Quando usare Gatling invece:**

- Esperti JVM/Scala nel team
- Bisogno di report built-in sbalorditivo
- Test di scenari HTTP complessi
- Requisiti in materia di sostegno alle imprese

**Perché k6 è meglio per la maggior parte delle applicazioni ASP.NET Core:**

- JavaScript è più accessibile
- Configurazione ed esecuzione più semplici
- Meglio per controlli rapidi CI/CD
- Più semplice per un semplice test HTTP

### k6 vs Artiglieria

**Artiglieria** è un altro strumento di test del carico JavaScript.

| Caratteristica | k6 | Artiglieria |
|---------|----|---------|
| **Definizione della prova** | codice JavaScript | YaML + ganci JS |
| **Prestazioni** | Più veloce (Go) | Più lento (Node.js) |
| **Facilità d'uso** | Code-based | YAML config-based |
| **Costruito per** | Prova di carico | Carico + prova funzionale |
| **Asserzioni** | Soglie eccellenti | Aspettative di base |
| **Estendibilità** | Estensioni | Plugin |

**Quando usare invece l'artiglieria:**

- Preferisci YAML sopra il codice
- Bisogno di test Socket.io
- Vuoi un carico combinato + test funzionali
- Già utilizzando l'ecosistema Node.js

**Perché k6 è meglio per la maggior parte delle applicazioni ASP.NET Core:**

- metriche più precise (Go vs Node.js)
- Sistema di soglia migliore
- API JavaScript Cleaner
- Più maturo e stabile

### k6 vs wrk/wrk2

**wrkCity name (optional, probably does not need a translation)** è uno strumento di benchmarking HTTP leggero.

|Caratteristiche | k6 |Wrk |
|---------|----|---------|
| **Facilità d'uso** | API di alto livello | Basso livello C + Lua |
| **Scenari** | Supporto scenario ricco | Solo base HTTP |
| **MetricsCity name (optional, probably does not need a translation)** | Comprensive | Basic |
| **Scripting** | JavaScript | Lua |
| **Usa caso** | Prova a pieno carico | Parametri di riferimento rapidi |

**Quando usare wrk invece:**

- Necessita assoluta minimal overhead
- Parametri di riferimento rapidi una tantum
- Prova delle prestazioni HTTP crude
- Prova di protocollo a basso livello

**Perché k6 è meglio per la maggior parte delle applicazioni ASP.NET Core:**

- Test molto più facili da scrivere
- Migliore reporting e metriche
- Supporto allo scenario (ramp-up, fasi)
- CI/CD friendly

### k6 vs Playwright/Cypress (basato sul browser)

**PlaywrightCity name (optional, probably does not need a translation)** e **CypressCity name (optional, probably does not need a translation)** sono strumenti di automazione del browser a volte utilizzati per i test di carico.

| Caratteristica | k6 | Playwright/Cypress |
|---------|----|---------|
| **Approccio** | HTTP a livello di protocollo | Browser reale |
| **Prestazioni** | Migliaia di VU | Decine di browser |
| **Uso delle risorse** | Peso leggero | Pesante (browser) |
| **Esecuzione JavaScript** | No | Sì |
| **Caso di utilizzo primario** | Prova di carico | Prova funzionale E2E |

**Quando usare Playwright/Cypress invece:**

- Necessità di testare l'esecuzione JavaScript
- È necessario verificare la renderizzazione del browser
- Prova delle SPA complesse
- Prova funzionale E2E

**Perché k6 è meglio per la maggior parte delle applicazioni ASP.NET Core:**

- Controllo a livello di protocollo sufficiente per le applicazioni rese dal server
- Necessità di simulare oltre 100 utenti simultanei
- Uso molto più efficiente delle risorse

### Sommario: Sweet Spot di k6

**Scegli k6 quando vuoi:**

- Test di carico veloce e preciso
- API JavaScript per sviluppatori-friendly
- Eccellente integrazione CI/CD
- Controllo HTTP a livello di protocollo (non è necessario browser)
- Ricco supporto scenario (fumo, carico, stress, picco, immersione)
- Strumenti moderni con un buon ecosistema
- Uso leggero delle risorse

**k6 è perfetto per:**

- API e servizi web
- App rese lato server
- Porte di prestazione CI/CD
- Test delle prestazioni basato sugli sviluppatori
- Applicazioni cloud-native

**Prendere in considerazione alternative se avete bisogno:**

- Test basati su browser (usare [PlaywrightCity name (optional, probably does not need a translation)](https://playwright.dev/))
- Supporto esteso del protocollo oltre l'HTTP (usare [JMeterCity name (optional, probably does not need a translation)](https://jmeter.apache.org/))
- Prove libere distribuite (uso [LocustCity name (optional, probably does not need a translation)](https://locust.io/))
- Bella built-in report (usare [GatlingCity name (optional, probably does not need a translation)](https://gatling.io/))
- GUI per tester non tecnici (uso [JMeterCity name (optional, probably does not need a translation)](https://jmeter.apache.org/))

## Passi successivi

Ora che hai capito cos'è k6, come installarlo, i tipi di test di performance disponibili, e perché k6 è un'ottima scelta per le applicazioni ASP.NET Core, sei pronto per iniziare a scrivere test reali.

**Continua a [Parte 2: Attuazione pratica](/blog/k6-testing-practical)** dove ci occuperemo di:

- Impostare l'ambiente di prova
- Scrivere il fumo, il carico, lo stress, il picco e le prove di immersione
- Verifica del comportamento della cache
- Simulazioni realistiche di viaggio utente
- Integrazione CI/CD con le azioni GitHub
- Rilevamento della regressione delle prestazioni
- Profilazione con dotTrace e dotMemory
- Migliori pratiche e risoluzione dei problemi

## Risorse

### k6 Documentazione

- [Documenti ufficiali](https://k6.io/docs/) - Documentazione completa k6
- [k6 API JavaScript](https://k6.io/docs/javascript-api/) - Tutte le API k6 disponibili
- [k6 esempi](https://github.com/grafana/k6-learn) - Script di prova di esempio
- [k6 metriche](https://k6.io/docs/using-k6/metrics/) - Comprendere le metriche
- [soglie k6](https://k6.io/docs/using-k6/thresholds/) - Impostazione dei criteri pass/fail

### Strumenti alternativi di prova del carico

- [Apache JMeter](https://jmeter.apache.org/) - Test del carico basato su Java
- [LocustCity name (optional, probably does not need a translation)](https://locust.io/) - Prove di carico basate su Python
- [GatlingCity name (optional, probably does not need a translation)](https://gatling.io/) - Prove di carico basate sulla scala
- [Artiglieria](https://www.artillery.io/) - Prova di carico Node.js
- [wrkCity name (optional, probably does not need a translation)](https://github.com/wg/wrk) - Strumento di benchmarking HTTP
- [PlaywrightCity name (optional, probably does not need a translation)](https://playwright.dev/) - Automazione del browser e testing