# Pruebas de carga Aplicaciones básicas ASP.NET con k6: Introducción

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

Su aplicación funciona perfectamente en su computadora portátil. Las pruebas de unidad pasan. Las pruebas de integración pasan. Usted despliega a la producción, y de repente todo se detiene. Quinientos usuarios reales golpean su página de inicio simultáneamente, y su servidor comienza a devolver 503 errores. Su estrategia de caché cuidadosamente diseñado? Resulta que no funciona como pensaba. Esa consulta de base de datos que pensó que era rápido? Está creando un cuello de botella a escala.

Este es el escenario de pesadilla que todos los desarrolladores temen, pero la mayoría no lo prueban. **Las pruebas de rendimiento no son opcionales - es la diferencia entre un lanzamiento exitoso y una página de emergencia de 3 AM.** Esta guía de dos partes le mostrará exactamente cómo prevenir este escenario utilizando k6, la herramienta de prueba de carga moderna que es lo suficientemente potente para aplicaciones empresariales pero lo suficientemente simple como para funcionar en su tubería CI/CD.

Esto es **Parte 1** de una serie de dos partes en el ensayo de carga con k6:

- **Parte 1 (este artículo)**: Introducción a k6, instalación, tipos de prueba, y por qué k6
- **[Parte 2: Aplicación práctica](/blog/k6-testing-practical)**: Pruebas de escritura, integración CI/CD, perfiles y ejemplos del mundo real

## Introducción

Las pruebas de rendimiento son críticas para cualquier aplicación de producción ASP.NET Core. Ya sea que esté construyendo un blog sencillo, una arquitectura de microservicio compleja o una aplicación empresarial, necesita saber cómo se comporta su aplicación bajo carga. ¿Manejará 100 usuarios simultáneos? 1,000? ¿Dónde están los cuellos de botella? ¿Funciona realmente su estrategia de almacenamiento en caché?

Esta guía completa le muestra cómo cargar las aplicaciones de prueba ASP.NET Core usando [k6](https://k6.io/) - una de las herramientas de prueba de carga de código abierto más potentes disponibles. [MinimalBlog](/blog/minimalblog-introduction) como nuestra aplicación de ejemplo (un simple blog basado en Markdown con memoria y caché de salida), las técnicas y patrones mostrados aquí se aplican a **cualquier aplicación ASP.NET Core**.

Al final de esta serie de dos partes, sabrás cómo:

- Instalar y configurar k6 en cualquier plataforma (Windows, Mac, Linux)
- Escribe pruebas completas de rendimiento para diferentes escenarios
- Integre k6 en su tubería CI/CD con las acciones GitHub
- Utilizar herramientas de perfilado (dotTrace, dotMemory) junto con k6 para encontrar cuellos de botella
- Implementar diferentes estrategias de prueba: pruebas de humo, carga, estrés, pico y remojo
- Configurar la detección de regresión de rendimiento para evitar que el código lento llegue a la producción

**¿Por qué MinimalBlog como ejemplo?** Es una aplicación ASP.NET Core 9.0 real con patrones comunes: Páginas Razor, almacenamiento en caché de memoria, almacenamiento en caché de salida, E/S de archivo y procesamiento de marcado. Los enfoques de prueba que aprenderá se aplican por igual a sus aplicaciones MVC, APIs Web, aplicaciones Blazor, o APIs mínimas.

[TOC]

## ¿Qué es k6 y por qué usarlo?

[k6](https://k6.io/) es una herramienta de prueba de carga moderna construida para desarrolladores. A diferencia de las herramientas más antiguas como JMeter o LoadRunner, k6 es:

- **Fácil de usar por el desarrollador**: Las pruebas están escritas en JavaScript (ES6+)
- **CLI-first**: Perfecto para tuberías CI/CD
- **Peso ligero**: binario único, sin dependencias
- **Precisión**: Escrito en Ir para métricas precisas
- **Scriptable**: Capacidades de programación completas para escenarios complejos
- **Listos para la nube**: Puede integrarse con k6 Cloud, Grafana, Prometheus

Para MinimalBlog, k6 es ideal porque:

1. **Podemos probar el caché.**: k6 puede verificar encabezados de caché y comportamiento
2. **Podemos simular tráfico real**: Probar múltiples usuarios concurrentes
3. **Podemos validar las reclamaciones de rendimiento**: Medir los tiempos de respuesta reales
4. **Podemos integrarnos con CI/CD**: Automatice las pruebas en nuestra tubería
5. **Podemos probar escenarios específicos**: Filtrado de categorías, publicaciones individuales, página de inicio

## Instalación de k6

### Instalación de Windows

**Opción 1: Uso de chocolate (recomendado)**

```powershell
choco install k6
```

**Opción 2: Uso de Winget**

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

**Opción 3: Instalación manual**

1. Descargar la última versión de Windows desde [Liberaciones de GitHub](https://github.com/grafana/k6/releases)
2. Extraer el `k6.exe` archivo
3. Añadir el directorio a su PATH o mover `k6.exe` a un directorio ya en PATH

**Verifique la instalación:**

```powershell
k6 version
```

### Instalación de Mac

**Opción 1: Uso de Homebrew (recomendado)**

```bash
brew install k6
```

**Opción 2: Uso de MacPorts**

```bash
sudo port install k6
```

**Opción 3: Instalación manual**

```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
```

**Verifique la instalación:**

```bash
k6 version
```

### Instalación Linux

**Opción 1: Usar administradores de paquetes**

Por **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
```

Por **Fedora/CentOS/RHEL**:

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

**Opción 2: Uso de Snap**

```bash
sudo snap install k6
```

**Opción 3: Instalación manual**

```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
```

**Opción 4: Uso de Docker**

```bash
docker pull grafana/k6:latest

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

**Verifique la instalación:**

```bash
k6 version
```

## Comprensión de la anatomía de prueba k6

Antes de sumergirnos en las pruebas, vamos a entender la estructura básica de una prueba de 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
}
```

Conceptos clave:

- **Usuarios virtuales (UV)**: Simulados usuarios concurrentes
- **Duración**: Cuánto tiempo dura la prueba
- **Comprobaciones**: Aserciones que no detienen la prueba
- **Umbrales**: Criterios de aprobación/fracaso
- **Métricas**: Tiempo de respuesta, rendimiento, tasa de error

## Tipos de pruebas de rendimiento

Antes de probar su aplicación, vamos a entender los cinco tipos principales de pruebas de carga y cuándo utilizar cada uno:

```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. Pruebas de humo

**Finalidad**: Verificar los trabajos del sistema bajo carga mínima

**Cuándo usar**:

- Después de cada cambio de código
- Antes de realizar pruebas más intensivas
- Como control de la cordura en CI/CD

**Características**:

- 1-2 VUs (usuarios virtuales)
- Duración corta (30s-1min)
- Funcionalidad básica de los ensayos

### 2. Pruebas de carga

**Finalidad**: Evaluar el rendimiento bajo la carga normal esperada

**Cuándo usar**:

- Establecer los resultados de referencia
- Para verificar que los SLA se cumplen
- Ensayos periódicos de regresión del rendimiento

**Características**:

- Número realista de usuarios
- Carga sostenida
- Duración típica: 5-15 minutos

### 3. Pruebas de estrés

**Finalidad**: Encuentra el punto de ruptura del sistema

**Cuándo usar**:

- Comprender los límites de capacidad
- Identificar los cuellos de botella
- Planificación de la escala

**Características**:

- Aumento gradual de la carga
- Empujar más allá de la capacidad normal
- Duración: 10-30 minutos

### 4. Pruebas de Spike

**Finalidad**: Comportamiento de prueba bajo picos repentinos de tráfico

**Cuándo usar**:

- Preparación para lanzamientos de productos
- Ensayo de autoescalado
- Validación del comportamiento de reserva

**Características**:

- Gran aumento repentino de la carga
- Duración corta del pico
- Duración total: 5-10 minutos

### 5. Pruebas de remojo (pruebas de resistencia)

**Finalidad**: Encontrar fugas de memoria y degradación con el tiempo

**Cuándo usar**:

- Antes de las principales liberaciones
- Pruebas de los servicios de larga duración
- Validación de la limpieza de recursos

**Características**:

- Niveles de carga normales
- Duración prolongada (horas o días)
- Monitor de la degradación

```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
```

## ¿Por qué k6 y no...?

Con tantas herramientas de prueba de carga disponibles, ¿por qué debería elegir k6? Comparemos k6 con las alternativas más populares:

### k6 vs Apache JMeter

**Apache JMeter** es el veterano de las herramientas de prueba de carga (desde 1999).

Característica:  k6  JMeter
|---------|----|---------|
| **Instalación** binario único, sin dependencias  Requiere Java, instalación más pesada
| **Definición de prueba** Código JavaScript XML o GUI
| **Uso de los recursos** Peso ligero (Go) Peso pesado (Java)
| **Integración CI/CD** Excelente (CLI-first) Requiere plugins
| **Curva de aprendizaje** Fácil para los desarrolladores  Steeper, centrado en la interfaz gráfica
| **Apoyo al Protocolo** HTTP, WebSockets, gRPC  Broader (FTP, JDBC, SMTP, etc.)

**Cuándo usar JMeter en su lugar:**

- GUI de necesidades para los evaluadores no técnicos
- Protocolos de prueba más allá de HTTP (JDBC, LDAP, SOAP)
- Ya tiene experiencia de JMeter en equipo
- Necesita extenso ecosistema de complementos

**Por qué k6 es mejor para la mayoría de las aplicaciones ASP.NET Core:**

- Pruebas de escritura más rápidas (JavaScript vs XML)
- Huella de recursos más ligera
- Mejor integración CI/CD
- Experiencia de desarrollador más moderna

### k6 vs Locust

**Locust** es una herramienta de prueba de carga basada en Python, popular en tiendas de Python.

Característica  k6  Locust
|---------|----|---------|
| **Idioma** JavaScript Python
| **Desempeño** Muy rápido (go runtime) Más lento (Python GIL)
| **Facilidad de uso** Simple JavaScript Pythónico, fácil
| **Pruebas distribuidas** k6 Nube (pagado)  Incorporado (gratuito)
| **Interfaz de usuario de la web** Excelente interfaz de usuario en tiempo real
| **Exportación de métricas** Muchos formatos CSV, web UI

**Cuándo usar Locust en su lugar:**

- Primer equipo de Python
- Necesidad de pruebas distribuidas gratuitas
- ¿Quieres la interfaz de usuario web en tiempo real durante las pruebas
- Lógica compleja de Python en pruebas

**Por qué k6 es mejor para la mayoría de las aplicaciones ASP.NET Core:**

- Mejor rendimiento para métricas precisas
- JavaScript más familiar para desarrolladores web
- Umbral/sintaxis de aseguramiento más limpio
- Mejor integración Prometeo/Grafana

### k6 vs Gatling

**Gatling** es una herramienta basada en Scala con excelentes informes.

Característica  k6  Gatling
|---------|----|---------|
| **Idioma** JavaScript Scala/Java
| **Informes** Básico (+ extensiones) Hermosos informes HTML incorporados
| **Curva de aprendizaje** Fácil  Moderado (Scala DSL)
| **Desempeño** # Excelente # # Excelente # # Excelente # # Excelente # # Excelente # # Excelente # # Excelente # # Excelente # #
| **Código abierto** Completamente abierto Abierto con complementos de empresa
| **Servicio en la nube** k6 Cloud  Gatling Enterprise

**Cuándo usar Gatling en su lugar:**

- Conocimientos de JVM/Scala en equipo
- Necesitan impresionantes informes incorporados
- Ensayo de escenarios HTTP complejos
- Necesidades de apoyo institucional

**Por qué k6 es mejor para la mayoría de las aplicaciones ASP.NET Core:**

- JavaScript es más accesible
- Configuración y ejecución más sencillas
- Mejor para comprobaciones rápidas de CI/CD
- Más sencillo para pruebas HTTP simples

### k6 vs Artillería

**Artillería** es otra herramienta de prueba de carga JavaScript.

Característica: Artillería.
|---------|----|---------|
| **Definición de prueba** Código JavaScript YAML + ganchos JS
| **Desempeño** Más rápido (Go) Más lento (Node.js)
| **Facilidad de uso** Basado en código  YAML basado en configuración
| **Construido para** Pruebas de carga  Carga + pruebas funcionales
| **Aserciones** Umbrales excelentes Expectativas básicas
| **Extensibilidad** Extensiones Plugins

**Cuándo usar Artillery en su lugar:**

- Prefiere YAML sobre el código
- Necesita Socket.io pruebas
- Quiere carga combinada + pruebas funcionales
- Ya utilizando el ecosistema Node.js

**Por qué k6 es mejor para la mayoría de las aplicaciones ASP.NET Core:**

- métricas más precisas (Go vs Node.js)
- Mejor sistema de umbrales
- API de JavaScript más limpia
- Más maduro y estable

### k6 vs wrk/wrk2

**wrk** es una herramienta de benchmarking HTTP ligera.

# Característica # # k6 # wrk #
|---------|----|---------|
| **Facilidad de uso** API de alto nivel  C de bajo nivel + Lua
| **Escenarios** Soporte de escenario rico  Basic HTTP sólamente
| **Métricas** Comprensivo  Básico
| **Guión** # JavaScript # # Lua #
| **Caso de uso** Pruebas de carga completa Parámetros rápidos

**Cuándo usar wrk en su lugar:**

- Necesidad de gastos generales mínimos absolutos
- Parámetros de referencia puntuales rápidos
- Probando el rendimiento HTTP en bruto
- Ensayos de protocolo de bajo nivel

**Por qué k6 es mejor para la mayoría de las aplicaciones ASP.NET Core:**

- Mucho más fácil de escribir las pruebas
- Mejores informes y métricas
- Apoyo al escenario (ramp-up, etapas)
- IC/CD friendly

### k6 vs Playwright/Cypress (Basado en navegador)

**Playwright** y **Cipreses** son herramientas de automatización del navegador que a veces se utilizan para las pruebas de carga.

Característica de Playwright/Cypress
|---------|----|---------|
| **Enfoque** Protocolo-nivel HTTP  Navegador real
| **Desempeño** Miles de VUs Decenas de navegadores
| **Uso de los recursos** Peso ligero Pesado (navegadores)
| **Ejecución de JavaScript** # No # # Sí #
| **Caso de uso primario** Pruebas de carga E2E pruebas funcionales

**Cuándo usar Playwright/Cypress en su lugar:**

- Necesidad de probar la ejecución de JavaScript
- Debe verificar la representación del navegador
- Ensayos de ZEPA complejos
- Ensayos funcionales de E2E

**Por qué k6 es mejor para la mayoría de las aplicaciones ASP.NET Core:**

- Pruebas a nivel de protocolo suficientes para aplicaciones de representación del servidor
- Necesidad de simular más de 100 usuarios concurrentes
- Uso mucho más eficiente de los recursos

### Resumen: punto dulce de k6

**Elija k6 cuando desee:**

- Pruebas de carga rápidas y precisas
- API JavaScript fácil de desarrollar
- Excelente integración CI/CD
- Pruebas HTTP a nivel de protocolo (no se necesita navegador)
- Soporte de escenario rico (humo, carga, estrés, pico, remojo)
- Herramientas modernas con buen ecosistema
- Uso ligero de los recursos

**k6 es perfecto para:**

- API y servicios web
- Aplicaciones renderizadas del lado del servidor
- Puertas de rendimiento CI/CD
- Pruebas de rendimiento impulsadas por el desarrollador
- Aplicaciones nativas de la nube

**Considere alternativas si necesita:**

- Pruebas basadas en el navegador (utilizar [Playwright](https://playwright.dev/))
- Compatibilidad extensa con el protocolo más allá de HTTP (usar [JMeter](https://jmeter.apache.org/))
- Pruebas distribuidas gratuitas (utilización [Locust](https://locust.io/))
- Hermosos informes incorporados (utilizar [Gatling](https://gatling.io/))
- GUI para los evaluadores no técnicos (utilización [JMeter](https://jmeter.apache.org/))

## Próximos pasos

Ahora que usted entiende lo que es k6, cómo instalarlo, los tipos de pruebas de rendimiento disponibles, y por qué k6 es una gran opción para las aplicaciones ASP.NET Core, usted está listo para empezar a escribir pruebas reales.

**Continuar a [Parte 2: Aplicación práctica](/blog/k6-testing-practical)** donde cubriremos:

- Configuración de su entorno de prueba
- Escribiendo pruebas de humo, carga, estrés, pico y remojo
- Comprobar el comportamiento de la caché
- Simulación realista del viaje del usuario
- Integración CI/CD con las acciones GitHub
- Detección de regresión de rendimiento
- Perfilar con puntoTrace y puntoMemoria
- Mejores prácticas y solución de problemas

## Recursos

### k6 Documentación

- [Oficial k6 docs](https://k6.io/docs/) - Documentación k6 completa
- [k6 API de JavaScript](https://k6.io/docs/javascript-api/) - Todas las API de k6 disponibles
- [Ejemplos de k6](https://github.com/grafana/k6-learn) - Ejemplo de scripts de prueba
- [métricas k6](https://k6.io/docs/using-k6/metrics/) - Comprender las métricas
- [Umbrales k6](https://k6.io/docs/using-k6/thresholds/) - Establecer criterios de aprobación/fracaso

### Herramientas alternativas de ensayo de carga

- [Apache JMeter](https://jmeter.apache.org/) - Pruebas de carga basadas en Java
- [Locust](https://locust.io/) - Pruebas de carga basadas en Python
- [Gatling](https://gatling.io/) - Pruebas de carga basadas en Scala
- [Artillería](https://www.artillery.io/) - Pruebas de carga de Node.js
- [wrk](https://github.com/wg/wrk) - Herramienta de benchmarking HTTP
- [Playwright](https://playwright.dev/) - Automatización y pruebas del navegador