A lo largo de mis seis años de trayectoria como QA Lead, he sido testigo de múltiples «revoluciones» metodológicas. Desde la consolidación de las arquitecturas de microservicios, hasta la adopción imperativa del enfoque Shift-Left Testing. Sin embargo, la disrupción que estamos experimentando hoy con la Inteligencia Artificial Generativa (GenAI) trasciende la mera optimización de procesos; estamos ante un cambio de paradigma en la forma en que concebimos, diseñamos y ejecutamos la automatización del aseguramiento de la calidad. En este artículo veremos, paso a paso, cómo automatizar pruebas con LLMs dentro del SDLC, con un caso práctico end-to-end.
En el actual ciclo de vida del desarrollo de software (SDLC), la presión por reducir el Time-to-Market choca frontalmente con la necesidad de garantizar una cobertura de pruebas exhaustiva. Históricamente, la redacción de test cases automatizados ha sido un cuello de botella al requerir tiempo, un profundo conocimiento técnico y un mantenimiento constante. Hoy, la implementación de modelos de lenguaje de gran tamaño (LLMs) dentro del entorno de QA no solo está agilizando estas tareas inherentes, sino que está empoderando a los equipos para generar arquitecturas de pruebas más robustas en una fracción del tiempo.
En este post, mi objetivo es alejarme del ruido mediático y aterrizar esta tecnología en el barro de nuestro día a día. Y para ello, vamos a ver un caso práctico y real de cómo utilizar GenAI para orquestar y automatizar pruebas End-to-End (E2E).
El nuevo arsenal del ingeniero de QA: prompt engineering para automatizar pruebas con LLMs
El mayor error que cometen las organizaciones al adoptar la IA generativa es tratarla como un simple buscador glorificado. Como profesionales de QA, no debemos pedirle a la IA que «escriba un test»; debemos proporcionarle un contexto arquitectónico, definir el framework, establecer los patrones de diseño y delimitar los criterios de aceptación. A esto lo llamamos Prompt Engineering enfocado a QA, la base real para automatizar pruebas con LLMs de forma fiable.
Para ilustrar este flujo de trabajo, vamos a plantear un escenario común pero crítico: la automatización del flujo de Checkout de un e-commerce utilizando Playwright y TypeScript, aplicando el patrón de diseño Page Object Model (POM).
Paso 1: definiendo el contexto (el prompt maestro)
El primer paso es construir un prompt altamente estructurado. En mi experiencia liderando equipos, he descubierto que los mejores resultados se obtienen cuando la instrucción incluye el rol, el stack tecnológico, los criterios de aceptación y las restricciones de código.
Por esta razón, la estructura del prompt exacto que utilizo como punto de partida en mi entorno de trabajo quedaría tal que así:
- Actúa como un Senior QA Automation Engineer experto en Playwright y TypeScript.
- Necesito automatizar un flujo E2E para el proceso de ‘Checkout’ de un e-commerce.
Contexto técnico:
– Framework: Playwright con TypeScript.
– Patrón de diseño: Page Object Model (POM).
– Fixtures: Utiliza el sistema de fixtures nativo de Playwright.
Criterios de Aceptación (User Story):
1. El usuario debe poder añadir un producto al carrito desde la PDP (Product Detail Page).
2. El usuario navega al carrito y verifica que el producto está presente.
3. El usuario completa el formulario de envío (Nombre, Apellido, Código Postal).
4. El usuario finaliza la compra y recibe un mensaje de «Order Completed».
Instrucciones:
1. Genera primero la clase del Page Object (CheckoutPage.ts) con sus respectivos locators (usa data-testid preferiblemente) y métodos.
2. Genera el archivo de prueba (checkout.spec.ts) importando el POM y aplicando validaciones (assertions) estrictas.
3. Incluye comentarios explicando las decisiones de diseño.
Paso 2: análisis e implementación del código generado
Al ejecutar este prompt en herramientas como ChatGPT (GPT-4) o Claude, el motor generativo no solo escupe líneas de código, sino que estructura la solución bajo los estándares de la industria que le hemos exigido.
Estructura del CheckoutPage.ts (Page Object)
// pages/CheckoutPage.ts
import { Page, Locator, expect } from '@playwright/test';
export class CheckoutPage {
readonly page: Page;
readonly addToCartBtn: Locator;
readonly cartIcon: Locator;
readonly firstNameInput: Locator;
readonly lastNameInput: Locator;
readonly zipCodeInput: Locator;
readonly continueBtn: Locator;
readonly finishBtn: Locator;
readonly orderConfirmation: Locator;
constructor(page: Page) {
this.page = page;
// Uso de data-testid para mayor resiliencia en los selectores
this.addToCartBtn = page.getByTestId('add-to-cart-button');
this.cartIcon = page.getByTestId('shopping-cart-link');
this.firstNameInput = page.getByTestId('firstName');
this.lastNameInput = page.getByTestId('lastName');
this.zipCodeInput = page.getByTestId('postalCode');
this.continueBtn = page.getByTestId('continue');
this.finishBtn = page.getByTestId('finish');
this.orderConfirmation = page.getByTestId('complete-header');
}
async addProductToCart() {
await this.addToCartBtn.click();
}
async goToCart() {
await this.cartIcon.click();
}
async fillShippingInfo(firstName: string, lastName: string, zipCode: string) {
await this.firstNameInput.fill(firstName);
await this.lastNameInput.fill(lastName);
await this.zipCodeInput.fill(zipCode);
await this.continueBtn.click();
}
async completeOrder() {
await this.finishBtn.click();
}
}
Estructura del checkout.spec.ts (el script de prueba)
// tests/checkout.spec.ts
import { test, expect } from '@playwright/test';
import { CheckoutPage } from '../pages/CheckoutPage';
test.describe('E2E Checkout Flow', () => {
let checkoutPage: CheckoutPage;
test.beforeEach(async ({ page }) => {
// Inicializamos el POM antes de cada test
checkoutPage = new CheckoutPage(page);
await page.goto('https://nuestro-ecommerce-demo.com/product/1');
});
test('Debe completar el flujo de compra exitosamente', async () => {
// 1. Añadir producto al carrito
await checkoutPage.addProductToCart();
// 2. Navegar al carrito
await checkoutPage.goToCart();
// Validamos que la URL es correcta
expect(checkoutPage.page.url()).toContain('/cart');
// 3. Completar información de envío
await checkoutPage.fillShippingInfo('Carlos', 'García', '28001');
// 4. Finalizar compra y verificar mensaje de éxito
await checkoutPage.completeOrder();
await expect(checkoutPage.orderConfirmation).toHaveText('Order Completed');
await expect(checkoutPage.orderConfirmation).toBeVisible();
});
});
Paso 3: refinamiento humano y el criterio del QA Lead
Llegados a este punto, la IA nos ha ahorrado aproximadamente el 70% del tiempo de boilerplating y redacción base. Sin embargo, el bagaje profesional de un QA Lead es lo que transforma un código funcional en un código mantenible a nivel Enterprise. ¿Qué ajustaría yo de este código generado antes de integrarlo a nuestro repositorio y pipeline de CI/CD?
- Gestión de datos (Data-Driven Testing): la IA nos ha puesto datos quemados (Carlos, García, 28001). En un entorno real, modificaría este script para que consuma un archivo JSON o utilice librerías como Faker.js, la cual, por cierto, también puedes pedirle a la IA que integre en el mismo script con un prompt adicional.
- Autenticación (State Storage): si el checkout requiere usuario logueado, le pediría a la IA que actualizase el test utilizando el guardado de estado de sesión de Playwright, para no tener que automatizar el login en cada test y reducir los tiempos de ejecución.
- Manejo de tiempos: aunque Playwright gestiona los auto-waits excelentemente, en aplicaciones con cargas asíncronas pesadas (animaciones de carritos, validaciones de tarjetas de crédito), el QA debe revisar que no haya condiciones de carrera (race conditions).
Beneficios colaterales en la consultoría informática
Con todo esto, y más allá de picar código, la implementación de la IA generativa está aportando un valor inmenso en otras áreas críticas del aseguramiento de la calidad:
- Generación de casos de prueba (Gherkin/BDD): podemos volcar los requerimientos funcionales de Jira en la IA y pedirle que nos extraiga todos los casos de uso afirmativos, negativos y edge cases en sintaxis Gherkin (Given-When-Then).
- Creación de datos sintéticos: el cumplimiento de normativas de privacidad nos impide usar datos de producción en entornos bajos (Staging/QA). Los LLMs son excepcionales generando estructuras JSON o CSV masivas con datos ficticios pero coherentes a nivel de negocio.
- Análisis de reportes de fallos: si un test en el pipeline nocturno falla, podemos alimentar a la IA con el log de Playwright para que diagnostique si el fallo se debe a un error de red, a un cambio en un selector o a un bug real.
Conclusión: la IA como copiloto, no como reemplazo
El ecosistema del desarrollo de software avanza a un ritmo vertiginoso. Como profesionales de la consultoría informática, adoptar estas tecnologías no es una opción, es una obligación de supervivencia. Sin embargo, tras seis años lidiando con la calidad de productos digitales, la principal lección que he extraído es que la GenAI es un copiloto extraordinario, pero un pésimo piloto al mando.
Automatizar pruebas con LLMs requiere supervisión, contexto de negocio y, sobre todo, una estrategia sólida de arquitectura de pruebas detrás. El código lo puede escribir una máquina en segundos; la estrategia sobre qué probar, cómo escalarlo y cómo alinear esas pruebas con el valor de negocio del cliente sigue, y seguirá siendo, el verdadero valor añadido del Ingeniero de QA.
