Inicio / Artículos

Playwright y TypeScript sin conocer TypeScript: un ingeniero, una capa de IA y cuatro etapas.

Un ingeniero de QA proveniente de Selenium y C# crea un framework Playwright en TypeScript con ayuda de IA: estructura, reglas de arquitectura, ganchos y cuatro puntos de control de tickets.

Editor: REACTAPP.TOP25 min de lectura5663 palabras

Fuentes: I Built a Playwright Framework in TypeScript Without Knowing TypeScript — Using AI

Un repositorio que se puede clonar, que contiene Habilidades y Reglas, además de un Playwright impulsado por MCP que explora la aplicación por sí solo, es algo fácil de prometer pero difícil de implementar. Este proyecto ya existe como proyecto funcional: clónalo, ejecuta una sola orden y las pruebas se ejecutarán en un sitio en vivo. La historia detrás de él comienza con un conjunto de herramientas heredadas y una pregunta sobre los lenguajes de programación.

La migración que nunca fue aprobada

Un equipo de control de calidad había pasado cuatro años intentando mantener funcional un conjunto heredado de herramientas Selenium, y algunos colegas que posteriormente pasaron a trabajar en desarrollo lo conocían desde aún antes. Su núcleo estaba formado por miles de pruebas de interfaz de usuario en C#, acumuladas a lo largo de los años por autores que en su mayoría ya habían dejado la empresa. Migrar a Playwright llevaba tiempo en la lista de deseos; es más rápido, más estable y más fácil de usar, pero la migración nunca se llevó a cabo.

La razón era trivial. Nadie tenía cien horas extra de ingeniería que dedicar a una reescritura cuyo valor empresarial era nulo, y un gerente no puede aprobar algo basándose únicamente en que “la nueva herramienta funciona mejor”. Siempre existen argumentos técnicos, pero cuanto más grande es el conjunto de herramientas, más costosa resulta la migración y menores parecen ser los beneficios obtenidos. La reescritura debe pagarse por adelantado y en su totalidad. Su retorno nunca se muestra como una cifra en un informe: se manifiesta en menos pruebas fallidas y soluciones más rápidas a lo largo de un par de años. Por lo tanto, la idea quedó en suspenso. Playwright y TypeScript seguían apareciendo en cada vez más anuncios de empleo, y no hacer nada se volvía cada vez más caro, tanto para el proyecto como para la persona involucrada.

Luego otro equipo inició algo nuevo, desde cero: sin herencias del pasado, sin un muro de pruebas que no pudieran romperse y sin necesidad de migraciones para justificar algo. Una propuesta para desarrollar automatización de interfaces de usuario y APIs llevó finalmente a Playwright y TypeScript al trabajo diario. También puso de manifiesto un hecho incómodo: Java y C# eran conocidos y tenían diez años de código de pruebas detrás, pero se trataba de pruebas y no de desarrollo, lo cual implica una profundidad diferente. JavaScript, TypeScript y Playwright en sí eran algo nuevo. Surgió una pregunta que habría sonado retórica hace dos años: ¿hasta qué punto el no conocer el lenguaje puede frenar a alguien en 2026, con la IA presente?

De dónde surgió el experimento

Ningún día en particular desencadenó este cambio. Se fue desarrollando a partir de la percepción de que simplemente probar y escribir pruebas no conduce a ningún resultado. El equipo de control de calidad se mantiene ocupado no mediante el conteo de errores o líneas de código, sino a través de la mejora de la calidad del producto mediante procesos, documentación, automatización y comunicación; con el paso de los años, un enfoque sistemático ha superado a los esfuerzos individuales.

Dos factores impulsaron las cosas en la misma dirección.

Una de las iniciativas provino de un bot de trading de criptomonedas escrito en Python con Claude Code por alguien que no conocía Python. La ejecución comenzó con la emoción de un primer éxito, pero terminó en colapso una vez que el código superó la comprensión de todos, y nadie pudo explicar por qué fallaban las pruebas ni cómo repararlas. La lección fue la brecha entre crear código y construir un sistema: el bot funcionaba, pero no podía mantenerse. No existía ningún mapa del proyecto, las correcciones generaban nuevos problemas en parejas, y los tokens desaparecían en intentos por describir síntomas en lugar de buscar causas.

Otra presión provino del trabajo diario, donde la IA se infiltraba gradualmente en las rutinas de control de calidad. Las pruebas abarcaban un proceso que iba desde la tarea hasta la prueba final, la definición de reglas para que el modelo las siguiera al pie de la letra, y el logro de que todo el flujo fuera reproducible y controlable. Los colegas utilizaban la IA como un buscador más inteligente o como una máquina expendedora de código. Casi nadie la integró en un sistema que la hiciera predecible, lo cual parecía una oportunidad desperdiciada, ya que es la parte sistemática la que aporta valor.

Esos dos enfoques dieron origen al proyecto Playwright, planteado como una hipótesis: hasta dónde puede llegar un ingeniero con sólidos conocimientos básicos si la IA se encarga de escribir, y si es posible crear un marco de pruebas completo sin escribir ni una sola línea en un lenguaje que el ingeniero no pueda leer con fluidez.

¿Por qué TypeScript y no C# o Java?

La primera comprobación fue la obvia. Playwright también existe para C# y Java, por lo que quizás no era necesario cambiar de lenguaje. Resultó que la diferencia no radicaba en el control del navegador. Esa parte es idéntica en todas partes, con la misma API, los mismos selectores y los mismos navegadores. La diferencia está en cómo se organizan y ejecutan las pruebas.

En JavaScript y TypeScript, Playwright incluye un ejecutor de pruebas nativo que permite la ejecución paralela, el uso de fixtures, la generación de informes y el seguimiento automático. En C# y Java no existe nada similar. Los equipos optan por lo que ya utiliza su ecosistema, ya sea xUnit, NUnit, JUnit o TestNG, y Playwright simplemente proporciona clases base para ellos, por lo que la organización y el paralelismo deben implementarse manualmente. Esa es la verdadera limitación: no se trata de una sintaxis extraña o de la falta de un método, sino de tener que reinventar la rueda, incluyendo el paralelismo, el aislamiento de datos por hilo, las conexiones y la generación de informes, problemas que ya han sido resueltos una vez y que es mejor evitar. Junto a esto había una opción que llegaba completamente lista, en un lenguaje que nadie conocía. Playwright creció junto a JavaScript, por lo que es algo nativo y no un elemento externo.

Qué significa realmente “construido sin conocimiento previo”

Calificar el proyecto como construido sin conocimientos sería más que inexacto; sería una mentira flagrante. Detrás de ello hay diez años de experiencia en pruebas de calidad: desarrollo de procesos desde cero y pruebas de todo tipo de sistemas, desde aplicaciones web y APIs hasta aplicaciones móviles. Esa experiencia fue lo que impidió que el trabajo se ahogara en un mar de código generado. La sintaxis de TypeScript y Playwright siempre fue un factor decisivo a favor.

Algunos cursos fueron de ayuda. Entre los experimentos anteriores y esta implementación, varios cursos de Anthropic trataron sobre el diseño de agentes, la concatenación de habilidades y la redacción de tareas para la IA. Complementaron la experiencia sin reemplazarla. Lo importante era la actitud. El proyecto no surgió de un programador que pedía algunas pruebas, sino de un ingeniero que le indicó al modelo las reglas, los límites arquitectónicos y lo que necesitaba verificarse, y luego lo dejó actuar dentro de esos límites, lo que convirtió un intercambio caótico en un proceso gestionado.

Un esqueleto, con dos reservas

Hay dos puntos que deben señalarse antes de describir la estructura y sus decisiones.

En primer lugar, el proyecto es un esqueleto y no un producto listo para ser utilizado, adaptado o modificado. Se comparte con el fin de mostrar un enfoque, no para afirmar que es perfecto. Quienes busquen una herramienta ya preparada se decepcionarán, mientras que quienes busquen un modelo para desarrollar un sistema basado en la IA lo encontrarán. Los equipos tienen sus propias limitaciones, requisitos de seguridad e integraciones, y un diseño adecuado para una demostración pública puede requerir una reestructuración significativa al implementarse dentro de sistemas corporativos de autenticación única, autenticación multifactor, reglas especiales para datos de prueba y un sistema de gestión de pruebas. Por lo tanto, la lógica detrás del código es la parte portable.

En segundo lugar, el conjunto de herramientas era mínimo. Consistía en Claude Code con la suscripción básica de veinte dólares al mes, Visual Studio Code como editor, un servidor MCP configurado para Playwright que permitía al modelo explorar la aplicación por sí mismo y, probablemente lo más importante, una mente fresca y algo de tiempo libre. No había soluciones corporativas costosas, ni infraestructura compleja, ni ejecutores de pruebas distribuidos. Todo funciona en una computadora portátil ordinaria, lo cual forma parte del mensaje: para comenzar no se necesita nada sobrenatural, solo una comprensión de lo que se está construyendo y el deseo de hacerlo.

Qué abarca el proyecto y cómo está organizado

El objetivo es Toolshop, una tienda en línea de demostración pública creada para practicar la automatización. La elección es importante: no se trata de un sistema cerrado ni de un contexto empresarial, por lo que cualquiera puede clonar el repositorio, instalar las dependencias con una sola orden y ejecutar pruebas en un sitio en vivo, sin necesidad de crear cuentas ni buscar documentación.

La suite cuenta con treinta y siete pruebas, treinta y cuatro que pasan y tres que fallan intencionadamente para que el informe muestre cómo se ve un fallo. Las pruebas de API cubren la lógica del servidor, las pruebas de interfaz cubren la interfaz misma, y las pruebas híbridas crean estado a través de la API antes de verificarlo en el navegador. Eso es suficiente para demostrar la arquitectura, pero muy poco para decir algo sobre el alcance del producto, el cual depende de un producto específico y de sus riesgos empresariales, y no de cuántas pruebas contenga una demostración. La estructura de directorios:

config/
 env.ts // The only place where environment variables are read
 timeouts.ts // Timeouts, also in one place
core/
 run-user.ts // The user registered by this specific run
 global-setup.ts // Register → UI login → data snapshot → download OpenAPI spec
 global-teardown.ts // Cleanup after the run: remove favorites and the user
 allure-labels.ts // Parses [Section / Subsection] from the test name into report structure
 allure-categories.ts // Buckets for triaging failures in the report
api/
 generated/schema.d.ts // Types generated from OpenAPI, never touched by hand
 types.ts // Domain types derived from the schema
 client.ts // openapi-fetch, paths and params checked by the compiler
 contract.ts // Runtime validation of API responses against the schema
 auth.api.ts // Typed clients on top of api/client.ts
pages/
 base.page.ts // Base page class
 components/ // Elements present on every page (site header)
 auth/ // Page Objects for authorization pages
 account/ // Account area: account, profile, favorites
 shop/ // Catalog, product page, checkout
fixtures/
 base.fixture.ts // All dependency injection, test/expect only imported from here
data/ // Strings and routes, so they don’t live inside tests
utils/ // Logger, reference data snapshot
tests/
 auth/ // Everything auth-related in one folder
   auth.api.spec.ts // API: login, token lifetime
   registration.api.spec.ts
   login.ui.spec.ts // UI: login form, errors, logout
 catalog/
   products.api.spec.ts
   catalog.ui.spec.ts
 cart/
   cart.ui.spec.ts
 favorites/
   favorites.api.spec.ts
   favorites.hybrid.spec.ts // Hybrid: state via API, verification via UI
 profile/
   profile.hybrid.spec.ts
 contract/
   contract.api.spec.ts // Matching live API responses against the spec
 demo/ // Tests tagged @demo that fail on purpose
docs/ // Feature maps, checklists, test cases, plans
.claude/ // AI layer: rules, skills, agents, hooks```

Decisiones de estructura que permiten escalar

  • Primero las funcionalidades, luego las capas. Una elección puede parecer extraña al principio, pero determina cuán bien se escalará todo: las pruebas se agrupan por funcionalidad, y la capa es un sufijo en el nombre del archivo, como en login.ui.spec.ts, auth.api.spec.ts y checkout.hybrid.spec.ts. Un desarrollador que modifica la lógica de autorización encuentra todas las pruebas relacionadas en tests/auth/ sin tener que buscar en tres carpetas diferentes. Con treinta pruebas nadie se da cuenta, y un layout basado en capas se ve ordenado. Pero con trescientas pruebas, tests/ui/ se convierte en un desorden de sesenta archivos, ya que cualquier cambio en una funcionalidad afecta a todas las pruebas que pertenezcan a ella, independientemente de la capa. Las pruebas dispersas convierten el análisis en una tarea de búsqueda.
  • Cuando incluso las características se vuelven abarrotadas. Con miles de pruebas, una carpeta de características puede llegar a contener cientos de archivos. El siguiente paso es utilizar subcarpetas según subfunciones o escenarios, como tests/auth/login/, tests/auth/registration/ y tests/auth/password-reset/, lo cual extiende la misma idea de mantener el contexto junto al código. De igual manera, cientos de pruebas no deberían compartir un único archivo, ya que eso genera un documento ilegible e imposible de revisar.
  • El híbrido como punto de partida. La demostración se divide en pruebas de API, UI e híbridas, pero un proyecto real no necesita replicarla ni crear tres capas por funcionalidad. Puede que no haya una API independiente que valga la pena probar, o bien las pruebas de UI ya pueden ser híbridas, con condiciones previas establecidas a través de la API o la base de datos y solo la parte relacionada con la interfaz se verifica en el navegador. Eso es legítimo, porque la separación por separado es un error. Escribir pruebas de UI híbridas desde el primer día evita las pruebas de UI puras que transfieren el estado a través del navegador y consumen minutos. La estructura es un medio, y cada abstracción adicional aumenta el mantenimiento.

Cuatro decisiones que explican el resto

El repositorio registra catorce decisiones arquitectónicas en .claude/rules/architecture.md, y cada una responde a “¿por qué de esta manera?” y no a “¿qué es esto?”. Cuatro de ellas se relatan aquí, ya que es mejor dejarlas en el repositorio en lugar de parafrasearlas.

Cada ejecución registra a su propio usuario

La configuración habitual es una cuenta de prueba compartida por todas las pruebas. Eso sigue siendo válido hasta que el conjunto de pruebas crece y se ejecutan en paralelo. Entonces, una prueba vacía el carrito justo cuando otra verifica si hay un producto en él, lo que genera un fallo que aparece una vez cada veinte ejecuciones y nunca en la propia máquina del depurador.

La regla parece sencilla: cada ejecución cuenta con su propio entorno aislado. Esto es diferente a prometer evitar datos compartidos o limpiarlos posteriormente. Significa que físicamente no hay nadie con quien chocar. En la demostración pública, un usuario nuevo registrado en global-setup cumple con esa función. Un entorno corporativo podría bloquearlo mediante límites de usuarios, entidades compartidas o un proceso de recreación de datos ya en uso. El principio se mantiene, pero el método para crear el entorno aislado es una cuestión aparte.

El mismo razonamiento lleva a retries: 0. Una repetición funciona como un silenciador y no como un seguro: tiende a ocultar una verdadera condición de carrera y pospone los problemas hasta el momento en que causan más daño. Una prueba que necesita repetirse no es inestable, sino que está reportando un fallo de aislamiento, y ese informe merece ser analizado. El costo es claro: en la demostración, registrar a un usuario requiere una solicitud y siempre tiene éxito, mientras que en otros casos el mecanismo será diferente.

Los tipos provienen de la especificación, y una prueba de contrato verifica dicha especificación

Se trata de dos verificaciones distintas que se confunden constantemente.

  • La primera se realiza en tiempo de compilación. La API cuenta con un documento OpenAPI y los tipos se generan a partir de él; por lo tanto, un campo mencionado en el código pero ausente en la especificación impide que el proyecto se compile. Esto tarda dos segundos y no requiere ninguna solicitud al servidor.
  • El segundo pregunta si el servidor realmente cumple con sus propias especificaciones. Un tipo generado no puede demostrarlo, ya que solo verifica la concordancia con el documento. Las pruebas de contrato se ejecutan en la API en producción y comparan las respuestas reales con el esquema. Ya en la primera ejecución encontraron una discrepancia en la ruta: el documento indicaba products/{productId} mientras que el código utilizaba products/{id}. Otra vez demostraron que el filtro del catálogo llamaba a by_category_slug, un parámetro que en absoluto figura en las especificaciones. El servidor lo acepta y las pruebas dan resultado positivo, por lo que todo “funciona”. Pero un parámetro ajeno al contrato no puede desviarse de él; solo puede desaparecer silenciosamente con el tiempo.

Por lo tanto, una prueba de contrato no sirve para verificar si un endpoint funciona, sino para comprobar si se trata del endpoint acordado por todos.

Un token que dura trescientos segundos

El diseño obvio consistía en iniciar sesión una vez antes de ejecutar el proceso, guardar el token en un archivo y permitir que cada proceso lo leyera. Casi se siguió ese enfoque. Pero el token de esta API dura exactamente trescientos segundos, lo cual se verifica mediante una prueba dedicada que compara dos campos dentro del token; además, la suite de pruebas dura más tiempo que eso. La prueba más lenta terminaría con un token inválido y fallaría con un código 401, lo cual parece un problema de permisos y no una expiración, por lo que la depuración comenzaría en el lugar equivocado.

Por eso el archivo almacena credenciales y no tokens. Cada proceso mantiene su propio token en memoria y lo renueva tempranamente. De esto se deriva una consecuencia: siempre se debe obtener el token justo donde se vaya a utilizar, y nunca guardarlo en una variable al principio de un bloque. Una sola línea de ese tipo vuelve a generar el mismo problema que el diseño buscaba eliminar.

Los datos de referencia de la instantánea se obtienen una vez y el estado mutable nunca

Las categorías, las marcas y la página del producto no cambian entre ejecuciones. Se pueden obtener una sola vez antes del inicio y entregarse a las pruebas, de modo que las treinta pruebas no soliciten siempre la misma lista. Los favoritos, el carrito y el perfil nunca deben formar parte de dicha instantánea, ya que las pruebas mismas los modifican. Tomar una instantánea del estado mutable no es una optimización; genera datos desactualizados, ya que una prueba lee lo que era cierto cinco segundos antes, falla, y alguien busca un error en una aplicación que en realidad no lo tiene.

La limpieza sigue la misma lógica. Se ejecuta en orden, primero las entidades y luego sus propietarios, y nunca falla; las permisos insuficientes solo generan una advertencia. Una desmontaje fallida convierte una sola prueba roja en una ejecución roja con una explicación incorrecta, el peor tipo de resultado negativo.

La capa de IA

Considere lo que sucede cuando Claude Code se abre en una carpeta de proyecto y recibe la solicitud “escribir pruebas para el carrito”. El modelo solo tiene esa solicitud y nada más. No sabe que las cuentas compartidas están prohibidas, que los localizadores deben provenir de un mapa verificado, ni que hacer afirmaciones sobre un contador global en un conjunto de pruebas paralelo es una trampa. Adivina, y lo hace bastante bien, por lo que el código parece decente y probablemente funcione. La mayoría de las personas se detienen en ese punto y lo consideran trabajo con IA.

La capa de IA reformula el problema. La pregunta deja de ser qué adivinará el modelo y pasa a ser qué debe saber y qué posiblemente nunca hará. Está compuesta por cinco componentes, cada uno con su propia función.

  • CLAUDE.md, siempre cargado. Un archivo en la raíz del proyecto que se carga al inicio de cada sesión. Funciona como una introducción para un nuevo colega, en este caso el modelo, resumido en dos pantallas: qué es el proyecto, dónde se encuentran las cosas, los cinco puntos más importantes y qué está estrictamente prohibido. La palabra “siempre” establece el límite, ya que cada conversación paga por el archivo en contexto. Solo se incluye lo que se necesita en cada ocasión. Cuarenta convenciones de estilo pertenecen a un archivo separado al que hace referencia.
  • reglas/, razones y no comandos. Estos archivos contienen decisiones arquitectónicas, convenciones de código y procedimientos del navegador. Una instrucción indica que no se debe elevar el token a una variable. Una regla explica que el token dura trescientos segundos, por lo que uno elevado a la parte superior muere durante la ejecución y provoca un error 401 en las pruebas más lentas. Con la razón en mano, el modelo no necesita una prohibición específica: comprende la categoría del problema y lo detecta en entornos desconocidos.
  • habilidades/, procedimientos con un control de acceso. Una habilidad es una guía para una tarea concreta: pasos, una descripción, frases desencadenantes, un modelo designado y una lista de herramientas permitidas. La lista de herramientas representa un límite real y no documentación. La habilidad que genera casos de prueba no puede ejecutar comandos, por lo que no puede iniciar pruebas por precaución, por más interesada que esté.
  • agentes: una entidad separada con menos derechos. Hay dos razones prácticas que lo justifican. Una es el contexto: una extracción completa de una página con todos sus atributos genera miles de tokens de información irrelevante, y si eso llega a la conversación principal, el marcado desplaza las discusiones sobre la lista de verificación. Un agente funciona en su propio contexto y devuelve un resultado, no materia prima. La otra razón son los límites: el agente de investigación no tiene acceso al código de prueba, por lo que la exploración solo produce documentación y no código como hecho concreto. El agente encargado de escribir pruebas podría no ejecutar el conjunto de pruebas, así que escribir sin ejecutar es suficiente en sí mismo.
  • ganchos/, aplicados de forma obligatoria y sin ser recordados. Una regla en prosa permanece en vigor mientras alguien la recuerde, por lo que las prohibiciones más severas se convierten en ganchos: pequeños scripts que se ejecutan antes de una acción y pueden vetarla. Los tipos generados y .env son ineditables. git push --force, --no-verify y --amend son rechazados automáticamente. Un gancho ni persuade ni explica nada posteriormente. La acción no tiene lugar, y la respuesta indica la razón y la ruta adecuada.

En una sola línea cada uno: CLAUDE.md es la lectura obligatoria para los recién llegados, las reglas son los estándares del equipo, las habilidades son las guías de proceso, los agentes son pasantes con acceso limitado, y los ganchos son los torniquetes que permanecen cerrados.

El mismo nivel en un ticket en vivo

Las abstracciones solo tienen sentido una vez que una tarea real pasa por ellas. Tomemos PROJ-431, “pagar un pedido con tarjeta”. El orden habitual de trabajo no tiene nada que ver con la IA: alguien prueba la función manualmente, alguien elabora una lista de verificación, alguien la convierte en casos de uso y alguien las automatiza. Una persona puede hacer las cuatro tareas o tres personas pueden dividirlas. Para el pipeline no importa quién las hace, y ese es el punto, porque el pipeline se superpone al proceso existente en lugar de reemplazarlo. El número de la tarea es el hilo conductor de todo, preferible a los nombres de funciones o ramas, ya que perdura más allá de los cambios de nombre y reasignaciones.

Paso uno: la lista de verificación

El ingeniero de QA inicia la habilidad y le proporciona el número. Dado que MCP está conectado a Jira, la habilidad lee directamente el ticket, incluyendo la descripción, los criterios de aceptación y, con frecuencia lo más útil, los comentarios en los que un desarrollador explicó parte del comportamiento sin actualizar la descripción. Si no hay MCP o el ticket está vacío, el ingeniero describe la función en la instrucción. El pipeline necesita una entrada y no le importa de dónde provenga.

Luego comienza la fase para la cual todo fue creado. La herramienta no obtiene una lista de verificación a partir del texto del ticket; en su lugar, activa al agente de investigación, que ingresa al entorno de la aplicación, ya sea local o de pruebas, visita las páginas relacionadas con la función, hace clic en los elementos, lee el DOM en tiempo real, llama a la API por sí mismo y compara las respuestas con las especificaciones. Solo después de eso se elabora la lista de verificación, basada en lo que realmente existe y no en lo que prometía el ticket. Los criterios de aceptación son datos de entrada, no la verdad, y la mitad de las discrepancias entre ellos y la realidad constituyen los primeros errores de la tarea, detectados antes incluso de que exista algún código.

Se generan dos archivos, y lo más importante aquí es mantenerlos separados. El primero es la lista de verificación: escenarios de negocio priorizados en el formato del equipo, y no verificaciones de elementos. Un borde rojo en un campo no constituye un escenario; en cambio, cuando a un usuario se le impide usar la tarjeta de otra persona y se le explica el motivo, sí lo es. El segundo archivo es el mapa de funcionalidades, que contiene localizadores verificados, campos de API, reglas de validación y problemas detectados durante el proceso. La lista de verificación representa el resultado directo de la tarea, mientras que el mapa sirve como referencia para los pasos siguientes. El ingeniero de QA lee la lista de verificación, elimina lo que es innecesario, agrega lo que solo una persona conoce, y esa revisión funciona como una barrera: nada avanza sin la aprobación correspondiente.

Paso dos: casos de prueba

Quien haya realizado el primer paso puede continuar, o otra persona si las pruebas manuales y la automatización se separan. Una segunda habilidad comienza con el mismo número de tarea y localiza por sí sola la lista de verificación y el mapa. El ingeniero elige qué cubrir, todo o solo lo acordado. Esta habilidad convierte esos elementos en casos y resuelve un aspecto por caso: la capa a la que pertenece la verificación.

  • Las reglas impuestas por el servidor se convierten en pruebas API.
  • Lo que ve el usuario se convierte en pruebas de interfaz de usuario.
  • Una verificación que requiere quince clics de configuración para una sola afirmación se convierte en una híbrida, con el estado generado a través de la API y solo la parte visible revisada a simple vista.

Los errores aquí cuestan más que los casos mal redactados, porque generan una cobertura lenta y superpuesta que nadie se atreve a eliminar posteriormente. Esta habilidad también incluye una sección de servicios para cada caso: datos a utilizar, localizadores, qué debe ser único, qué se limpia y bajo qué cuenta. Para una persona parece papeleo; para el siguiente paso, es una especificación lista para usar. El ingeniero la revisa y aprueba, lo cual constituye la segunda etapa. Los equipos en Qase o TestRail pueden agregar una habilidad aquí que sube los casos aprobados a través de API y posteriormente los marca como automatizados.

Paso tres: automatización

La habilidad de automatización también toma el número de la tarea y obtiene la lista de verificación, los casos y el mapa en sí. Su primer paso es inesperado: verifica cuán actualizado está el mapa. Cada sección lleva una fecha de verificación, y todo lo que tiene más de un mes deja de considerarse un hecho y se convierte en una afirmación. La habilidad ni rechaza ni confía ciegamente. Mueve las partes obsoletas a una sección de riesgos del plan y deja la decisión en manos de un humano, ya sea para realizar nuevamente el reconocimiento o aceptar el riesgo. Un localizador obsoleto aparecerá de todos modos, pero tres pasos después como un tiempo de espera cuya causa está oculta.

A continuación viene el plan: qué archivos aparecen, qué datos utiliza cada prueba, qué se crea antes de ejecutarla y qué se elimina después, qué métodos de página y cliente se añaden y qué preguntas quedan sin responder. El plan es la tercera y más importante etapa, ya que determina si es seguro ejecutar el lote en paralelo, y modificarlo posteriormente resulta costoso.

Una vez aprobado, el plan pasa al agente encargado de escribir el código, cuya característica distintiva es que no inventa localizadores. Si falta uno necesario en el mapa, ni lo supone similar ni oculta la deficiencia omitiendo la prueba. Deja una nota en el código indicando que nadie verificó el localizador y lo reporta. La prueba sigue sin escribirse y falla, lo cual es correcto, porque el problema permanece visible y no desaparece.

Lo que antes eran comandos separados ahora se encuentra dentro de este paso: ejecutar, leer el error, corregir. Cada prueba cuenta con dos intentos; luego el agente se detiene y admite la derrota. Una ejecución secuencial verifica la lógica, mientras que dos ejecuciones paralelas verifican el aislamiento. No se necesita ningún botón adicional, ya que nada de esto requiere una decisión humana. Se trata de un procedimiento establecido en las reglas.

Las prohibiciones aquí son claras y no están sujetas a debate:

  • No desactive una prueba fallida para que la ejecución muestre color verde.
  • No aumente el número de intentos.
  • No debilite disimuladamente una verificación para que se ajuste al comportamiento observado.

Si la aplicación se comporta incorrectamente, un resultado rojo en la prueba es el adecuado.

Paso cuatro: revisión y confirmación

La revisión y el commit pertenecen a dos habilidades distintas y no a una sola; se trata de una separación intencionada, ya que un paso que comienza con la intención de hacer un commit tiende más a encontrar razones para no hacerlo. La revisión implica conocimientos específicos del proyecto que ningún revisor genérico posee: qué significa aquí una entidad compartida, qué pone en riesgo un token en la parte superior de un bloque, por qué es engañoso confiar en un contador global. Cada entrada de su lista proviene de una falla anterior en este proceso. Para evitar que esta separación se convierta en una mera formalidad, la revisión deja una “huella digital” del diff que analizó, y el commit se niega a continuar si ese diff ha cambiado desde entonces. Eso no es un bloqueo; es una pregunta con una respuesta exacta: ¿se revisó este código, o fue otro código? La diferencia entre un proceso y un hábito radica justo ahí.

Cuando toda la cadena se ha ejecutado, PROJ-431 contiene toda la información: qué se investigó, qué se eligió para verificar, qué está cubierto por la automatización, qué queda como tarea manual y qué no se automatizará y por qué. La razón no es el amor por la documentación. Seis meses después, la pregunta sobre por qué un escenario no está cubierto surgirá de alguien en una retrospectiva, y debe existir una respuesta.

Qué sobrevive a la tarea

El principal riesgo del entorno no es un código mal generado, sino que el contexto se deteriore y se convierta en un desorden seis meses después, sin que nadie sepa en qué archivo confiar. Por lo tanto, los artefactos tienen tres períodos de vida separados, y está prohibido mezclarlos.

  • Las reglas permanecen vigentes mientras dure el proyecto y solo cambian junto con el código.
  • El mapa de características dura años y pertenece a las características y no a la tarea. Se amplía con secciones fechadas, nuevas páginas y nuevos problemas, sin ser reconstruido por cada tarea.
  • Las listas de verificación, casos y planes pertenecen a una tarea y se convierten en historia cuando esta se cierra.

Sin esa división, un año después el mapa de localización existe en diez copias dispersas entre los números de tarea, la mitad de ellas incorrectas y sin forma de saber cuál es la mitad correcta. Cuando el mapa de una característica crece, como ocurre con los mapas de las características más grandes, la solución es similar a la del código: dividirlo en partes a lo largo de límites naturales como páginas, subcaracterísticas o escenarios, y mantener un índice breve que indique dónde se encuentra cada elemento. También rige una regla estricta de entrada: solo los hechos verificados pueden incluirse en el mapa, es decir, lo que el agente realmente vio en la aplicación en tiempo real, con fecha de registro. Las conjeturas y las reseñas de los tickets no son válidas. Un mapa que las acepte es inútil dentro de un sprint, y posteriormente no es posible separar los hechos de las conjeturas.

Nada de esto constituye una receta universal. Cuatro pasos en el proceso, cinco componentes de la capa de IA, compuertas y ciclos de vida de los artefactos son un arreglo posible. Los equipos difieren en número de miembros, producto y herramientas, por lo que la mitad de los detalles se aplicarán de manera distinta. Algunos métodos funcionarán, otros requerirán adaptaciones y algunos no funcionarán, y eso es aceptable.

El punto central permanece igual en todo caso. Construya la capa de IA adecuadamente, de modo que el modelo siga las reglas del equipo dentro de sus límites, utilizando sus artefactos, y que el trabajo rutinario quede fuera de las responsabilidades del equipo: leer solicitudes, redactar casos similares, seleccionar capas, buscar ubicaciones, volver a ejecutar y reparar fallos, revisar una y otra vez los mismos problemas. Los ingenieros de QA no serán reemplazados ni se cancelará el proceso existente. Simplemente, se deja de invertir tiempo en lo que puede ser transferido a otros.

¿Sigue siendo necesario contar con empleados senior?

Se necesitan ingenieros senior más que nunca, pero con un rol cambiado. David Heinemeier Hansson ha observado que la mejor aceleración impulsada por agentes que ha visto provino de las personas más experimentadas, aquellas capaces de determinar si los resultados del agente son adecuados para su uso.

Antes, los ingenieros eran valorados por escribir código, conocer la sintaxis y completar tareas rápidamente, lo cual tenía sentido cuando el código era el producto principal. Con la IA, ese valor ha cambiado drásticamente, no solo en un pequeño porcentaje. La máquina escribe el código, y el ser humano decide qué escribir, por qué, dentro de qué límites y cómo verificar que el resultado no sea falso.

Imagínese a dos especialistas. El primero abre Claude Code y solicita una prueba de inicio de sesión. La prueba se escribe, se aprueba, y el especialista se siente productivo, lo cual es cierto en la actualidad. Un mes después, la prueba deja de funcionar; la causa es un misterio. Se aplican parches de forma aleatoria mientras se consumen tokens, y al final todo se vuelve a escribir o la prueba se elimina y se olvida.

El segundo especialista diseña primero: cómo se aíslan las pruebas, qué patrón sigue el cliente de API, cómo se gestionan los tokens y qué ocurre con el estado que cambia entre pruebas. Solo entonces se le da la instrucción al modelo: escribir una prueba de inicio de sesión según estas reglas.

El primero contiene una prueba que funciona actualmente. El segundo alberga un sistema que sigue funcionando, porque se basa en una arquitectura sólida y no en la suerte. En un pequeño conjunto de pruebas, la diferencia es imperceptible, salvo que el primero completa diez o quince pruebas en diez minutos, mientras que el segundo necesita dos horas o más para hacer lo mismo. Después de cien, doscientas o mil pruebas y de cincuenta a cien ejecuciones del pipeline, la diferencia se vuelve evidente.

¿Significa eso que es necesario aprender un lenguaje de programación?

Sí, aunque no para escribir código. Se necesita un lenguaje para comprender lo que genera la IA, para detectar errores en el código generado, para revisar las solicitudes de integración y para decidir qué llega a la rama principal. La sintaxis es una herramienta. Una estructura compleja basada en la memoria está fuera del alcance de un probador en un territorio desconocido, pero la arquitectura es un terreno conocido: cómo debería ser el sistema, cómo se mantienen aisladas las pruebas, cómo se organizan las cadenas de procesamiento y qué contiene un buen informe. Esa base hizo posible el proyecto Playwright.

La arquitectura no surge de una instrucción. La IA puede proponerla, a veces bien, pero la arquitectura es una elección entre respuestas y no solo una respuesta. Un modelo ofrece cinco opciones que todas parecen razonables. Cuál de ellas se adaptará en seis meses, con diez veces más pruebas y requisitos modificados, no es algo que se genere automáticamente. Surge de la experiencia, de los conocimientos adquiridos al corregir pruebas defectuosas, al averiguar por qué una prueba funciona localmente pero falla en CI, y al descubrir que existe un acoplamiento oculto en una cuenta compartida listo para causar problemas.

Las empresas no necesitan a personas que solo presionan botones y escriben instrucciones en Claude Code o Cursor. Esas personas son numerosas y seguirán siéndolo, y el mercado está repleto de programadores que creen haber encontrado la mina de oro, aunque eso solo dura poco tiempo. Lo que se busca son personas que entiendan por qué la IA hace algo, se den cuenta cuando se equivoca, enfoquen las tareas de modo que el modelo proporcione una solución funcional y no un error pulido, y construyan un sistema en lugar de seguir introduciendo tokens en interminables rondas de “intenta de nuevo, no así”.

La experiencia en procesos, automatización y pipelines no es algo obsoleto. Es la base para un trabajo competente con la IA y distingue a quien crea caos de quien construye un sistema. Antes, el conocimiento servía para realizar tareas a mano. Ahora sirve para asignar tareas a la IA y verificar los resultados. El rol ha cambiado, pero el valor de la experiencia no. Es más fácil de observar, ya que, junto con la IA, queda claro quién simplemente genera contenido y quién comprende qué se generó y por qué.

Lo que muestra el experimento

Se construyó un marco en un lenguaje que su creador no conoce, y esta no es una historia sobre genialidad. Es una historia sobre no intentar adivinar qué haría la IA, y en su lugar dedicar tiempo a explicar las reglas del juego: qué está permitido, qué no y por qué de esta manera y no de otra. Es aburrido, no tiene nada que ver con la atmósfera general y se necesita tiempo antes de que aparezca el primer resultado. Eso es exactamente lo que funciona.

El repositorio no demuestra que los ingenieros estén obsoletos ni que los lenguajes hayan dejado de ser importantes. Es una prueba en tiempo real de cómo cambia el papel del ingeniero cuando el valor se desplaza de escribir código a definir tareas, diseñar sistemas y verificar resultados. Escribir código a mano sigue siendo una habilidad. Se ha sumado una segunda habilidad que resulta igual de importante: comprender qué se generó, por qué y qué vendrá a continuación.

La IA no reemplaza al ingeniero. Se convierte en el asistente junior más rápido y obediente imaginable, incansable, que nunca discute y siempre está listo para intentarlo de nuevo. Tiene un defecto: presenta una solución correcta y tonterías absolutas con la misma confianza, y solo quien comprende el trabajo puede distinguirlas. Por eso, el ingeniero debe seguir al mando como quien conoce el destino y el camino, y no como alguien que simplemente sostiene el volante.