JavaScript

JavaScript

Tutorial JavaScript: Introducción a pruebas en JS

Vitest y Jest: descubre los beneficios de las pruebas en desarrollo software y cómo implementarlas efectivamente con frameworks de testing.

Aprende JavaScript y certifícate

¿Por qué hacer pruebas?: Conceptos básicos

Las pruebas de software son una parte fundamental del desarrollo profesional que a menudo se subestima, especialmente cuando estamos aprendiendo a programar. Muchos desarrolladores comienzan verificando su código manualmente: ejecutan la aplicación, prueban algunas funcionalidades y asumen que todo funciona correctamente. Sin embargo, este enfoque tiene serias limitaciones cuando los proyectos crecen en complejidad.

Beneficios de las pruebas automatizadas

  • 1. Detección temprana de errores: Las pruebas permiten identificar problemas antes de que lleguen a producción, cuando son más costosos de corregir.
// Sin pruebas: descubrimos tarde que esto falla con ciertos inputs
function calculateDiscount(price, percentage) {
  return price * percentage; // Error: no divide entre 100
}

// Con pruebas: detectamos el problema inmediatamente
test('applies 20% discount correctly', () => {
  expect(calculateDiscount(100, 20)).toBe(20);
});
  • 2. Documentación viva: Las pruebas actúan como una forma de documentación que siempre está actualizada y muestra exactamente cómo debe comportarse el código.
// Esta prueba documenta claramente el comportamiento esperado
test('should capitalize first letter of each word', () => {
  expect(capitalizeWords('hello world')).toBe('Hello World');
});
  • 3. Refactorización segura: Permite mejorar el código existente con la confianza de que no estamos rompiendo funcionalidades.
// Podemos refactorizar esta función...
function sumArray(numbers) {
  let total = 0;
  for (let i = 0; i < numbers.length; i++) {
    total += numbers[i];
  }
  return total;
}

// ...a una versión más moderna y concisa usando el método reduce que vimos en programación funcional
function sumArray(numbers) {
  return numbers.reduce((sum, num) => sum + num, 0);
}

// Y nuestras pruebas nos aseguran que sigue funcionando igual
  • 4. Diseño mejorado: Escribir pruebas nos obliga a pensar en la interfaz y comportamiento de nuestro código antes de implementarlo, lo que normalmente resulta en un diseño más limpio y modular.

Conexión con conceptos previos

Las pruebas se complementan perfectamente con los conceptos que hemos visto anteriormente:

  • Funciones puras (Programación Funcional): Las funciones puras que vimos en módulos anteriores son ideales para las pruebas unitarias, ya que:
    • Siempre devuelven el mismo resultado para las mismas entradas
    • No tienen efectos secundarios
    • No dependen de estado externo
// Función pura del módulo de programación funcional
function filterPositive(numbers) {
  return numbers.filter(num => num >= 0);
}

// Es muy fácil de probar
test('filters out negative numbers', () => {
  expect(filterPositive([5, -3, 10, -7, 0])).toEqual([5, 10, 0]);
});
  • Calidad de código (ESLint): Mientras que ESLint nos ayuda a mantener un código limpio y evitar errores sintácticos, las pruebas verifican que nuestro código funciona correctamente a nivel lógico. Son herramientas complementarias para asegurar la calidad.

Tipos de pruebas

Existen diferentes niveles de pruebas, cada uno con propósitos específicos:

Pruebas unitarias: Verifican el funcionamiento correcto de unidades individuales de código (generalmente funciones o métodos) de forma aislada.

Pruebas de integración: Comprueban que diferentes partes del sistema funcionan correctamente juntas.

Pruebas end-to-end (E2E): Simulan el comportamiento de un usuario real interactuando con la aplicación completa.

El costo de no hacer pruebas

No implementar pruebas puede parecer que ahorra tiempo inicialmente, pero a largo plazo genera:

  • Deuda técnica: Cada vez es más difícil modificar el código sin introducir regresiones.
  • Ciclos de desarrollo más lentos: Pasar más tiempo depurando problemas que escribiendo nuevas funcionalidades.
  • Menor confianza: Incertidumbre sobre si los cambios romperán algo en producción.

Enfoque pragmático

No es necesario alcanzar el 100% de cobertura de pruebas. Un enfoque pragmático consiste en:

// Priorizar pruebas para lógica de negocio crítica
function calculateMortgage(principal, rate, years) {
  const monthlyRate = rate / 100 / 12;
  const payments = years * 12;
  return (
    (principal * monthlyRate * Math.pow(1 + monthlyRate, payments)) /
    (Math.pow(1 + monthlyRate, payments) - 1)
  );
}

// Esta función merece buenas pruebas con diferentes escenarios
test('calculates mortgage correctly for standard case', () => {
  expect(calculateMortgage(200000, 3.5, 30)).toBeCloseTo(898.09);
});

Estructura de una prueba básica

Una buena práctica es seguir el patrón "Arrange-Act-Assert" para organizar tus pruebas:

test('should filter out negative numbers', () => {
  // Arrange (preparar): configuramos los datos de prueba
  const numbers = [5, -3, 10, -7, 0];
  
  // Act (actuar): ejecutamos la función que queremos probar
  const result = filterPositive(numbers);
  
  // Assert (verificar): comprobamos que el resultado es el esperado
  expect(result).toEqual([5, 10, 0]);
});

Herramientas principales: Vitest/Jest fundamentales

En el ecosistema de JavaScript, contar con frameworks de pruebas robustos es esencial para implementar una estrategia de testing efectiva. Dos de las herramientas más destacadas son Jest y Vitest, que proporcionan todo lo necesario para escribir y ejecutar pruebas de manera eficiente.

Jest y Vitest: ¿Qué son?

Jest es un framework de pruebas desarrollado por Facebook que se ha convertido en el estándar para muchos proyectos JavaScript.

Vitest es un framework más reciente diseñado específicamente para proyectos que utilizan Vite como bundler, ofreciendo una experiencia de desarrollo más rápida.

Instalación básica

Para comenzar a usar estas herramientas en tu proyecto:

// Instalación de Jest
// npm install --save-dev jest

// Instalación de Vitest
// npm install --save-dev vitest

Nuestro ejemplo integrador: Utility functions

A lo largo de esta lección, trabajaremos con un pequeño módulo de funciones utilitarias que podrían venir de nuestras lecciones previas de programación funcional:

// utils.js
export function capitalize(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

export function calculateTax(amount, taxRate) {
  return amount * taxRate / 100;
}

export function filterItems(items, predicate) {
  return items.filter(predicate);
}

Estructura básica de una prueba

Tanto Jest como Vitest comparten una sintaxis similar para escribir pruebas:

// utils.test.js
import { expect, test } from 'vitest'; // o 'jest'
import { capitalize, calculateTax } from './utils';

test('capitalizes the first letter of a string', () => {
  expect(capitalize('hello')).toBe('Hello');
});

test('calculates tax amount correctly', () => {
  expect(calculateTax(100, 10)).toBe(10);
});

Funciones principales para organizar pruebas

Ambos frameworks proporcionan funciones para ayudarte a estructurar tus pruebas:

import { describe, test, expect } from 'vitest';
import { capitalize, calculateTax, filterItems } from './utils';

describe('String utils', () => {
  test('capitalizes the first letter of a string', () => {
    expect(capitalize('hello')).toBe('Hello');
    expect(capitalize('world')).toBe('World');
  });
  
  test('returns empty string when input is empty', () => {
    expect(capitalize('')).toBe('');
  });
});

describe('Number utils', () => {
  test('calculates tax amount correctly', () => {
    expect(calculateTax(100, 10)).toBe(10);
    expect(calculateTax(200, 5)).toBe(10);
  });
});
  • test() (o it()): Define un caso de prueba individual
  • describe(): Agrupa pruebas relacionadas en bloques lógicos

Funciones para configuración y limpieza

Cuando necesitas preparar datos o configuraciones antes de tus pruebas:

import { describe, test, beforeEach, expect } from 'vitest';
import { filterItems } from './utils';

describe('Array filters', () => {
  let items;
  
  // Se ejecuta antes de cada prueba en este bloque
  beforeEach(() => {
    items = [
      { id: 1, name: 'Item 1', price: 10, inStock: true },
      { id: 2, name: 'Item 2', price: 20, inStock: false },
      { id: 3, name: 'Item 3', price: 30, inStock: true }
    ];
  });
  
  test('filters items by availability', () => {
    const inStockItems = filterItems(items, item => item.inStock);
    expect(inStockItems.length).toBe(2);
    expect(inStockItems[0].id).toBe(1);
    expect(inStockItems[1].id).toBe(3);
  });
  
  test('filters items by price threshold', () => {
    const expensiveItems = filterItems(items, item => item.price > 15);
    expect(expensiveItems.length).toBe(2);
    expect(expensiveItems[0].id).toBe(2);
    expect(expensiveItems[1].id).toBe(3);
  });
});
  • beforeEach(): Ejecuta código antes de cada prueba
  • afterEach(): Ejecuta código después de cada prueba
  • beforeAll() y afterAll(): Ejecutan código una sola vez antes/después de todas las pruebas

Matchers: Verificación de resultados

Los "matchers" son funciones que te permiten verificar valores de diferentes maneras:

test('demonstration of common matchers', () => {
  // Igualdad
  expect(2 + 2).toBe(4);                   // Igualdad estricta (===)
  expect({ name: 'test' }).toEqual({ name: 'test' });  // Igualdad profunda
  
  // Arrays
  expect([1, 2, 3]).toContain(2);          // Contiene elemento
  expect([1, 2, 3]).toHaveLength(3);       // Tiene longitud específica
  
  // Números
  expect(10).toBeGreaterThan(5);           // Mayor que
  expect(5).toBeLessThanOrEqual(5);        // Menor o igual que
  
  // Strings
  expect('hello world').toMatch(/world/);  // Coincide con regex
  expect('hello').toContain('ell');        // Contiene substring
});

Ejecución de pruebas

Para ejecutar tus pruebas, puedes configurar scripts en tu package.json:

{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run"
  }
}

Y luego ejecutarlos con:

npm test      # Modo observador: ejecuta pruebas cuando los archivos cambian
npm run test:run  # Ejecuta las pruebas una vez

Ejemplo:

Crea los siguientes archivos en la carpeta testing-demo para realizar la prueba:

Calculator.js

// Función para sumar dos números
export function sum(a, b) {
  return a + b;
}

// Función para restar dos números
export function subtract(a, b) {
  return a - b;
}

// Función para verificar si un número es par
export function isEven(number) {
  return number % 2 === 0;
}

calculator.test.js

import { expect, test, describe } from 'vitest';
import { sum, subtract, isEven } from './calculator.js';

describe('Calculadora básica', () => {
  test('suma 1 + 2 igual a 3', () => {
    expect(sum(1, 2)).toBe(3);
  });

  test('resta 5 - 3 igual a 2', () => {
    expect(subtract(5, 3)).toBe(2);
  });

  test('verifica si un número es par', () => {
    expect(isEven(4)).toBe(true);
    expect(isEven(7)).toBe(false);
  });
});

Ejecuta npm test

Terminología: pruebas, fixtures, aserciones

Para dominar el testing en JavaScript es importante familiarizarse con algunos términos clave. Estos conceptos te ayudarán a comunicarte efectivamente con otros desarrolladores y a entender mejor la documentación de las herramientas de pruebas.

Conceptos básicos de pruebas

Aserciones (Assertions): Son declaraciones que verifican si un valor cumple con ciertas condiciones. Forman el núcleo de cualquier prueba.

test('capitalize function works correctly', () => {
  // Esto es una aserción
  expect(capitalize('hello')).toBe('Hello');
});

Suite de pruebas: Un grupo de pruebas relacionadas, generalmente implementado con la función describe.

describe('String utility functions', () => {
  test('capitalize works with regular strings', () => {
    // ...
  });
  
  test('capitalize handles empty strings', () => {
    // ...
  });
});

Cobertura de código: Mide qué porcentaje de tu código está siendo probado. Aunque no debes obsesionarte con alcanzar el 100%, es un buen indicador de qué tan completas son tus pruebas.

# Ejecutar pruebas con análisis de cobertura
npm test -- --coverage

Preparación de datos para pruebas

Cuando escribes muchas pruebas, a menudo necesitas crear datos de ejemplo repetidamente. Hay varias formas de hacerlo:

1. Datos de prueba simples

test('filterItems works with predicate', () => {
  const items = [
    { id: 1, price: 10, inStock: true },
    { id: 2, price: 20, inStock: false },
    { id: 3, price: 5, inStock: true }
  ];
  
  const cheap = filterItems(items, item => item.price < 15);
  expect(cheap.length).toBe(2);
  expect(cheap[0].id).toBe(1);
  expect(cheap[1].id).toBe(3);
});

2. Funciones auxiliares

Cuando necesitas crear datos similares en múltiples pruebas, puedes usar funciones auxiliares:

function createItem(overrides = {}) {
  return {
    id: 1,
    name: 'Test Item',
    price: 10,
    inStock: true,
    ...overrides
  };
}

function createItemList() {
  return [
    createItem({ id: 1, name: 'Item 1' }),
    createItem({ id: 2, name: 'Item 2', price: 20 }),
    createItem({ id: 3, name: 'Item 3', inStock: false })
  ];
}

test('filters in-stock items', () => {
  const items = createItemList();
  const inStockItems = filterItems(items, item => item.inStock);
  expect(inStockItems.length).toBe(2);
});

test('filters by price range', () => {
  const items = createItemList();
  const affordableItems = filterItems(items, item => item.price <= 15);
  expect(affordableItems.length).toBe(2);
});

Este enfoque, a veces llamado "fixtures", te permite mantener tus pruebas más limpias y mantener la consistencia en tus datos de prueba.

Aislamiento en pruebas

Para pruebas unitarias efectivas, a menudo necesitas aislar la función que estás probando de sus dependencias:

// En vez de probar esta función que tiene dependencias externas...
function getUserData(userId) {
  return fetch(`/api/users/${userId}`)
    .then(response => response.json());
}

// ...podemos simular la dependencia para pruebas más controladas
import { vi } from 'vitest';

// Reemplazar temporalmente fetch con una implementación simulada
global.fetch = vi.fn().mockResolvedValue({
  json: () => Promise.resolve({ id: 1, name: 'Test User' })
});

test('getUserData returns user information', async () => {
  const user = await getUserData(1);
  expect(user.name).toBe('Test User');
});

Este concepto de simulación (conocido como "mocking") es una técnica avanzada que exploraremos más a fondo en lecciones posteriores.

Ejemplo integrador: Mejorando nuestras pruebas

Veamos cómo podríamos evolucionar las pruebas para nuestra función filterItems:

import { describe, test, expect } from 'vitest';
import { filterItems } from './utils';

describe('filterItems function', () => {
  // Paso 1: Prueba básica
  test('filters items with a basic predicate', () => {
    const numbers = [1, 2, 3, 4, 5];
    const evenNumbers = filterItems(numbers, n => n % 2 === 0);
    expect(evenNumbers).toEqual([2, 4]);
  });
  
  // Paso 2: Añadir más casos de prueba
  test('works with empty arrays', () => {
    const emptyArray = [];
    const result = filterItems(emptyArray, item => true);
    expect(result).toEqual([]);
  });
  
  test('works with complex objects', () => {
    const users = [
      { id: 1, name: 'Alice', age: 25 },
      { id: 2, name: 'Bob', age: 17 },
      { id: 3, name: 'Charlie', age: 30 }
    ];
    
    const adults = filterItems(users, user => user.age >= 18);
    expect(adults.length).toBe(2);
    expect(adults[0].name).toBe('Alice');
    expect(adults[1].name).toBe('Charlie');
  });
  
  // Paso 3: Probar comportamiento con predicados inválidos
  test('returns empty array when predicate is always false', () => {
    const items = [1, 2, 3];
    const result = filterItems(items, () => false);
    expect(result).toEqual([]);
  });
  
  // Paso 4: Probar borde de error
  test('throws error when predicate is not a function', () => {
    const items = [1, 2, 3];
    expect(() => filterItems(items, 'not a function')).toThrow();
  });
});

Este ejemplo muestra cómo podemos partir de una prueba simple y gradualmente expandirla para cubrir más casos y comportamientos límite, mejorando la robustez de nuestras pruebas.

Integración con tu flujo de trabajo

Las pruebas no deben ser una actividad aislada, sino una parte integral de tu proceso de desarrollo:

  1. Escribe pruebas junto con tu código - No las dejes para el final
  2. Ejecuta pruebas frecuentemente - Idealmente con cada cambio
  3. Arregla las pruebas fallidas inmediatamente - No dejes que se acumulen

Conexión con otras prácticas de calidad

Las pruebas se complementan perfectamente con otras prácticas que hemos visto:

  • ESLint detecta errores sintácticos y de estilo
  • Las pruebas verifican que el comportamiento funcional es correcto
  • La modularización (módulos ES6) hace que tu código sea más fácil de probar

Juntas, estas herramientas forman una red de seguridad que mejora significativamente la calidad de tu código y reduce los errores en producción.

Aprende JavaScript online

Otras lecciones de JavaScript

Accede a todas las lecciones de JavaScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Javascript

JavaScript

Introducción Y Entorno

Tipos De Datos

JavaScript

Sintaxis

Variables

JavaScript

Sintaxis

Operadores

JavaScript

Sintaxis

Estructuras De Control

JavaScript

Sintaxis

Funciones

JavaScript

Sintaxis

Funciones Cierre (Closure)

JavaScript

Sintaxis

Métodos De Strings

JavaScript

Sintaxis

Funciones Cierre (Closure)

JavaScript

Sintaxis

Operadores Avanzados

JavaScript

Sintaxis

Funciones

JavaScript

Sintaxis

Expresiones Regulares

JavaScript

Sintaxis

Estructuras De Control

JavaScript

Sintaxis

Arrays Y Métodos

JavaScript

Estructuras De Datos

Conjuntos Con Set

JavaScript

Estructuras De Datos

Mapas Con Map

JavaScript

Estructuras De Datos

Conjuntos Con Set

JavaScript

Estructuras De Datos

Funciones Flecha

JavaScript

Programación Funcional

Filtrado Con Filter() Y Find()

JavaScript

Programación Funcional

Transformación Con Map()

JavaScript

Programación Funcional

Reducción Con Reduce()

JavaScript

Programación Funcional

Funciones Flecha

JavaScript

Programación Funcional

Transformación Con Map()

JavaScript

Programación Funcional

Inmutabilidad Y Programación Funcional Pura

JavaScript

Programación Funcional

Clases Y Objetos

JavaScript

Programación Orientada A Objetos

Excepciones

JavaScript

Programación Orientada A Objetos

Encapsulación

JavaScript

Programación Orientada A Objetos

Herencia

JavaScript

Programación Orientada A Objetos

Polimorfismo

JavaScript

Programación Orientada A Objetos

This Y Contexto

JavaScript

Programación Orientada A Objetos

Patrón De Módulos Y Namespace

JavaScript

Programación Orientada A Objetos

Prototipos Y Cadena De Prototipos

JavaScript

Programación Orientada A Objetos

Destructuring De Objetos Y Arrays

JavaScript

Programación Orientada A Objetos

Manipulación Dom

JavaScript

Dom

Selección De Elementos Dom

JavaScript

Dom

Modificación De Elementos Dom

JavaScript

Dom

Eventos Del Dom

JavaScript

Dom

Localstorage Y Sessionstorage

JavaScript

Dom

Bom (Browser Object Model)

JavaScript

Dom

Callbacks

JavaScript

Programación Asíncrona

Promises

JavaScript

Programación Asíncrona

Async / Await

JavaScript

Programación Asíncrona

Api Fetch

JavaScript

Programación Asíncrona

Naturaleza De Js Y Event Loop

JavaScript

Programación Asíncrona

Websockets

JavaScript

Programación Asíncrona

Módulos En Es6

JavaScript

Construcción

Configuración De Bundlers Como Vite

JavaScript

Construcción

Eslint Y Calidad De Código

JavaScript

Construcción

Npm Y Dependencias

JavaScript

Construcción

Introducción A Pruebas En Js

JavaScript

Testing

Pruebas Unitarias

JavaScript

Testing

Accede GRATIS a JavaScript y certifícate

Ejercicios de programación de JavaScript

Evalúa tus conocimientos de esta lección Introducción a pruebas en JS con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Excepciones

JavaScript
Test

Transformación con map()

JavaScript
Código

Arrays y Métodos

JavaScript
Código

Reto Métodos de Strings

JavaScript
Código

Transformación con map()

JavaScript
Puzzle

Funciones flecha

JavaScript
Test

Selección de elementos DOM

JavaScript
Puzzle

API Fetch

JavaScript
Código

Encapsulación

JavaScript
Test

Mapas con Map

JavaScript
Código

Creación y uso de variables

JavaScript
Puzzle

Polimorfismo

JavaScript
Puzzle

Reto Funciones flecha

JavaScript
Código

Tipos de datos

JavaScript
Puzzle

Reto Operadores avanzados

JavaScript
Código

Reto Estructuras de control

JavaScript
Código

Estructuras de control

JavaScript
Puzzle

Pruebas unitarias

JavaScript
Proyecto

Inmutabilidad y programación funcional pura

JavaScript
Código

Funciones flecha

JavaScript
Puzzle

Polimorfismo

JavaScript
Test

Reto Polimorfismo

JavaScript
Código

Array

JavaScript
Código

Transformación con map()

JavaScript
Test

Reto Variables

JavaScript
Código

Gestor de tareas con JavaScript

JavaScript
Proyecto

Proyecto Modificación de elementos DOM

JavaScript
Proyecto

Manipulación DOM

JavaScript
Test

Funciones

JavaScript
Test

Conjuntos con Set

JavaScript
Código

Reto Prototipos y cadena de prototipos

JavaScript
Código

Reto Encapsulación

JavaScript
Código

Funciones flecha

JavaScript
Código

Async / Await

JavaScript
Código

Reto Excepciones

JavaScript
Código

Reto Filtrado con filter() y find()

JavaScript
Código

Reto Promises

JavaScript
Código

Creación y uso de variables

JavaScript
Test

Excepciones

JavaScript
Puzzle

Promises

JavaScript
Código

Funciones cierre (closure)

JavaScript
Test

Reto Herencia

JavaScript
Código

Herencia

JavaScript
Puzzle

Reto Async / Await

JavaScript
Código

Proyecto Eventos del DOM

JavaScript
Proyecto

Herencia

JavaScript
Test

Selección de elementos DOM

JavaScript
Test

Modificación de elementos DOM

JavaScript
Test

Reto Clases y objetos

JavaScript
Código

Filtrado con filter() y find()

JavaScript
Test

Funciones cierre (closure)

JavaScript
Puzzle

Reto Destructuring de objetos y arrays

JavaScript
Código

Callbacks

JavaScript
Código

Funciones

JavaScript
Puzzle

Mapas con Map

JavaScript
Test

Reducción con reduce()

JavaScript
Test

Callbacks

JavaScript
Puzzle

Manipulación DOM

JavaScript
Puzzle

Introducción al DOM

JavaScript
Proyecto

Reto Funciones

JavaScript
Código

Reto Funciones cierre (closure)

JavaScript
Código

Promises

JavaScript
Test

Reto Reducción con reduce()

JavaScript
Código

Async / Await

JavaScript
Test

Reto Estructuras de control

JavaScript
Código

Eventos del DOM

JavaScript
Puzzle

Introducción a JavaScript

JavaScript
Puzzle

Async / Await

JavaScript
Puzzle

Promises

JavaScript
Puzzle

Selección de elementos DOM

JavaScript
Proyecto

Filtrado con filter() y find()

JavaScript
Código

Callbacks

JavaScript
Test

Creación de clases y objetos Restaurante

JavaScript
Código

Reducción con reduce()

JavaScript
Código

Filtrado con filter() y find()

JavaScript
Puzzle

Reducción con reduce()

JavaScript
Puzzle

Conjuntos con Set

JavaScript
Puzzle

Herencia de clases

JavaScript
Código

Eventos del DOM

JavaScript
Test

Clases y objetos

JavaScript
Puzzle

Modificación de elementos DOM

JavaScript
Puzzle

Mapas con Map

JavaScript
Puzzle

Proyecto carrito compra agoodshop

JavaScript
Proyecto

Introducción a JavaScript

JavaScript
Test

Reto Mapas con Map

JavaScript
Código

Funciones

JavaScript
Código

Proyecto administrador de contactos

JavaScript
Proyecto

Reto Expresiones regulares

JavaScript
Código

Tipos de datos

JavaScript
Test

Clases y objetos

JavaScript
Test

Array

JavaScript
Test

Conjuntos con Set

JavaScript
Test

Array

JavaScript
Puzzle

Encapsulación

JavaScript
Puzzle

Clases y objetos

JavaScript
Código

Uso de operadores

JavaScript
Puzzle

Uso de operadores

JavaScript
Test

Estructuras de control

JavaScript
Test

Proyecto Manipulación DOM

JavaScript
Proyecto

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender los beneficios de las pruebas automatizadas
  • Diferenciar tipos de pruebas: unitarias, de integración y E2E
  • Implementar buenas prácticas y principios de pruebas efectivas
  • Explorar herramientas principales: Vitest y Jest
  • Aplicar un enfoque pragmático a la cobertura de pruebas