Asegurando el Módulo de Ventas: Pruebas de Integración con Firebase Emulators y Vitest
Introducción
En el desarrollo de TuTiendaWeb, la fiabilidad del módulo de ventas es fundamental. Asegurar que las operaciones de compra, actualización, consulta y eliminación de ventas funcionen correctamente, incluso bajo diversas condiciones, es crucial para la confianza del usuario y la integridad de los datos. Esta publicación explora cómo abordamos las pruebas de integración para el módulo de ventas, utilizando Firebase/Firestore Emulators y Vitest para crear un entorno de prueba robusto y eficiente.
Prerrequisitos
Para seguir esta guía, es útil tener conocimientos básicos de:
- TypeScript
- Firebase/Firestore
- Vitest (como framework de pruebas)
- Conceptos de emuladores de Firebase
Paso 1: Entendiendo el Alcance de las Pruebas de Ventas
Nuestro objetivo era cubrir una amplia gama de escenarios en el módulo de ventas. Esto incluyó:
createSale: Verificar la creación de ventas, asegurando que los totales se recalculen correctamente a partir de los ítems.updateSale: Probar actualizaciones con notación de punto (ej.items.0.cantidad) y la aplicación de descuentos.getSales: Validar la recuperación de ventas con filtros complejos (fecha, método de pago/entrega, cliente sensible a mayúsculas/minúsculas, límites).calculateSalesStats: Asegurar que las estadísticas de ventas se calculen correctamente, incluyendo el manejo de casos sin ventas.deleteSale/deleteSaleAction: Confirmar la eliminación de ventas y acciones relacionadas.createPublicSaleAction: Probar la creación de ventas sin sesión de usuario y la efectividad de las guardas de autenticación.
Paso 2: Configuración del Entorno de Pruebas con Emuladores
Los emuladores de Firebase son esenciales para las pruebas de integración, ya que permiten ejecutar pruebas contra una versión local y aislada de Firestore, sin incurrir en costos ni afectar datos en producción. Esto garantiza que las pruebas sean rápidas, consistentes y repetibles.
Para configurar los emuladores con Vitest, se utilizan los hooks beforeAll y afterAll para iniciar y detener la conexión al emulador, respectivamente. Es importante asegurarse de que el emulador de Firestore esté ejecutándose (ej. firebase emulators:start) antes de ejecutar las pruebas.
import { beforeAll, afterAll, describe, it, expect } from 'vitest';
import { initializeApp, getApps } from 'firebase/app';
import { getFirestore, connectFirestoreEmulator, collection, addDoc, getDoc, doc } from 'firebase/firestore';
// Configuración de Firebase para pruebas
const firebaseConfig = { projectId: 'tu-proyecto-test' };
let app;
let db;
beforeAll(async () => {
if (!getApps().length) {
app = initializeApp(firebaseConfig);
} else {
app = getApps()[0];
}
db = getFirestore(app);
// Conecta al emulador de Firestore en el puerto por defecto (8080)
connectFirestoreEmulator(db, 'localhost', 8080);
console.log('Conectado al emulador de Firestore');
});
afterAll(async () => {
// Limpieza o desconexión si es necesario. En muchos casos, los emuladores
// se gestionan externamente o mediante scripts CI/CD.
console.log('Pruebas de Firestore finalizadas');
});
// ... tus bloques de prueba de integración
Paso 3: Implementando Pruebas de Integración con Vitest
Una vez configurado el entorno, podemos escribir pruebas para cada operación de venta. Cada prueba debe ser independiente, preparar sus propios datos y verificar los resultados esperados. Aquí un ejemplo simplificado para la creación de una venta:
import { collection, addDoc, getDoc, doc } from 'firebase/firestore';
import { describe, it, expect } from 'vitest';
// 'db' se obtiene del setup en beforeAll
describe('Operaciones de Venta', () => {
it('debería crear y recuperar una venta correctamente', async () => {
const ventasCollection = collection(db, 'ventas');
const nuevaVenta = {
clienteId: 'cliente_123',
total: 250.00,
items: [{ productoId: 'prod_A', cantidad: 2, precioUnitario: 100 }],
estado: 'completado',
fechaCreacion: new Date()
};
// 1. Crear la venta
const docRef = await addDoc(ventasCollection, nuevaVenta);
// 2. Recuperar la venta
const fetchedDoc = await getDoc(doc(db, 'ventas', docRef.id));
// 3. Verificar los resultados
expect(fetchedDoc.exists()).toBe(true);
expect(fetchedDoc.data()).toEqual(expect.objectContaining({
clienteId: 'cliente_123',
total: 250.00,
estado: 'completado'
}));
});
it('debería filtrar ventas por cliente correctamente', async () => {
// Suponiendo que se han creado ventas previamente para este test
const querySnapshot = await db.collection('ventas')
.where('clienteId', '==', 'cliente_filtrado')
.get();
expect(querySnapshot.docs.length).toBeGreaterThan(0);
querySnapshot.docs.forEach(doc => {
expect(doc.data().clienteId).toBe('cliente_filtrado');
});
});
});
Resultados
La implementación de estas pruebas de integración completas ha resultado en un módulo de ventas extremadamente robusto para TuTiendaWeb. Al ejecutar 17 pruebas dedicadas en nuestro entorno, logramos la verificación de las funcionalidades clave, desde el cálculo de totales hasta el manejo de filtros complejos y acciones públicas, todo ello con la velocidad y fiabilidad que ofrecen los emuladores de Firebase. Esto nos proporciona una gran confianza en la estabilidad de las operaciones de ventas y en la calidad del código base.
Próximos Pasos
Considera ampliar la cobertura de pruebas para escenarios de borde más complejos, como transacciones fallidas o inconsistencias de datos. Explora también cómo integrar estas pruebas de forma más fluida en tu pipeline de CI/CD para garantizar que cada cambio se valide automáticamente antes de llegar a producción. La inversión en pruebas de integración con emuladores es un pilar fundamental para el desarrollo sostenible de aplicaciones de alta calidad.
Generated with Gitvlg.com