Las pruebas de integración son una farsa
- Detalles
- Publicado: Sábado, 11 Abril 2009 23:18
Las pruebas de integración son una farsa - son como un virus que se auto-reproduce y amenaza con infectar a todo el código, al proyecto, y al equipo con un dolor y sufrimiento sin fin.
Esperen un minuto... ¿¿¿cómo???
Lo digo en serio. Odio a las pruebas de integración. Las odio con ganas. Por supuesto, primero debería clarificar a lo que me refiero con pruebas de integración, porque, como muchos otros términos en el software, seguramente no estemos de acuerdo en su significado.
Utilizo el término prueba de integración para referirme a cualquier prueba cuyo resultado (éxito o fallo) dependa de una correcta implementación de más de una pieza de comportamiento no trivial.
Si, yo tamibén preferiría una definición más rigurosa, pero funciona para la mayoría de los casos. El punto es simple: en general prefiero no depender de pruebas que puedan fallar por una variedad de motivos. Estas pruebas generan más problemas de los que resuelven.
Escribimos pruebas de integración porque no podemos escribir pruebas unitarias perfectas. Todos conocemos el problema: todas las pruebas unitarias pasan, pero igualmente alguien encuentra un defecto. A veces podemos explicar esto encontrando una prueba unitaria obvia que faltaba, pero a veces no podemos. En estos casos, decidimos escribir una prueba de integración para asegurarnos que todas las implementaciones productivas que usamos en este camino de ejecución defectuoso ahora funcionen correctamente.
Hasta acá no es un gran problema. El monstruo recién aparece cuando pensamos esto:
"Si podemos encontrar defectos incluso aunque nuestras pruebas pasen el 100%, y si sólo podemos tapar estos agujeros con pruebas de integración, entonces mejor escribamos pruebas de integración por todos lados".
Mala Idea. Realmente mala.

¿Por qué es tan mala? Un poquito de aritmética nos va a ayudar a explicar la situación.
Supongamos que tenemos una aplicación web mediana, con 20 páginas, 10 de las cuales tienen formularios. Cada formulario tiene un promedio de 5 campos, y cada campo necesita un promedio de 3 pruebas para verificarlo completamente. La arquitectura tiene 10 capas, incluyendo los elementos web de presentación, las páginas web de presentación, presentación abstracta, un bridge HTTP hacia nuestro API de servicios, controladores, scripts de transacciones, repositorio de datos abstractos, implementaciones de repositorios de datos, mapeos SQL, ejecuciones SQL, y configuración de la aplicación. Un ciclo típido de request/response crea un stack trace de 30 cuadros de profundidad, alguno de los cuales los escribimos nosotros, y otros provienen de algún tipo de framework que estemos usando. ¿Cuántas pruebas necesitamos escribir para probar la aplicación de forma completa?
Al menos 10.000. Quizás un millón. Un millón.
¡¿Cuánto?! Consideremos 10 capas con 3 potenciales puntos de bifurcación en cada capa. Número de caminos de ejecución: 310 > 59.000 ¿Y qué tal con 4 bifurcaciones por capa? 410 > 1.000.000 ¿Y qué pasa con 3 bifurcaciones en 12 capas? 312 > 530.000 .
Para simplificar las cuentas, supongamos que sólo necesitamos 100.000 pruebas de integración para cubrir la aplicación. Las pruebas de integración usualmente interactúan con el sistema de archivos o conexiones de red, lo que significa que se ejecutan en promedio no más de 50 pruebas por segundo. La suite de 100.000 pruebas se ejecutaría en 2000 segundos, o 34 minutos. Esto significa que vamos a eejcutar la suite entera sólo cuando estemos listos a probarlo. Algunos equipos dejan que el sistema de integración continua haga esto, y esperan que ocurra lo mejor, perdiendo tiempo valioso cuando las pruebas fallan y se enteran una hora después.
¿Cuánto se tarda en escribir 100.000 pruebas? Si nos toma 10 minutos escribir cada prueba -esto incluye el tiempo para pensar, tiempo para mantener la base de datos de prueba, el servidor web, el servidor de aplicaciones, y así - entonces necesitamos 2778 días-humano de seis horas (o días-pareja, si usamos programación de a pares). Esto es lo mismo que 556 semanas-humano de cinco días (o semanas-pareja).
Incluso aunque haya sobreestimado por un factor de cinco, igualmente necesitariamos a dos personas tiempo completo por un año escribiendo pruebas Y un flujo constante de trabajo para mantenerlos ocupados las 6 horas del día Y no van a poder equivocarse, porque no tienen tiempo para re-escribir las pruebas.
No. Vamos a tener a estos programadores de pruebas escribiendo código productivo por la semana ocho.
Como no vamos a escribir todos estas pruebas, vamos a escribir las pruebas que podamos. Vamos a escribir las pruebas para los caminos de ejecuciones felices y algunos casos de error. No vamos a comprobar todos los campos de cada formulario. No vamos a comprobar a ver qué pasa el 29 de febrero. Vamos a escribir 50 pruebas por semana, lo que se traduce en 2500 pruebas en un año. No 100.000.
El 2.5% del número que necesitaríamos para probar la aplicación completa.
Incluso aunque escribieramos el 2.5% más importante, y sabiendo de toda la duplicación de las pruebas complementarias completas, sólo cubriríamos entre el 10% y el 80% de los caminos de ejecución, y no vamos a tener idea si estamos más cerca del 10% o del 80% hasta que el cliente empiece a usar la primera entrega.
¿Y'? ¿Ya te sentís afortunado?
Así que escribimos 2500 pruebas de integración. Quizás hasta llegamos a las 5000 pruebas. Cuando el cliente encuentra un defecto, ¿cómo lo arreglamos? Si, claro: con otro grupo de pruebas d eintegración. Mientras más pruebas de integración escribimos, más alimentamos una falsa sensación de seguridad (recordemos, con esas 10 pruebas de integración extra aumentamos la cobertura de caminos del ejecución del 5% al 5.01%). Esta falsa sensación de seguridad nos ayuda a sentirnos bien al entregar más código poco probado al cliente, quien a su vez encontrará más defectos, los cuales arreglaremos con aún más pruebas de integración. Con el paso del tiempo la cobertura de caminos de ejecución decrese porque la complejidad del código aumenta más rápido que nuestra capacidad para escribir pruebas de integración que lo cubran.
... y todavía te preguntás por qué pasás el 70% del tiempo respondiendo pedidos de soporte y mantenimiento.
Las pruebas de integración son una farsa. Son una pérdida de tiempo poco confiable y que se auto-reproduce. Es momento de que se vayan.
Basado en Integration tests are a scam, part 1.
-
rikoton
Permalinklas pruebas de integracion son importantes pero el problema q graficas es un abuso de las pruebas de integracion. no es necesario hacerlas cada vez q se hace un mantenimeinto o un pequeño cambio. eso es lo q yo opino y hago
-
Como dice el artículo: "El monstruo recién aparece cuando pensamos esto: Si podemos encontrar defectos incluso aunque nuestras pruebas pasen el 100%, y si sólo podemos tapar estos agujeros con pruebas de integración, entonces mejor escribamos pruebas de integración por todos lados."<br /><br />Obviamente que el artículo va al extremo, pero a mi entender hace un punto interesante: hacer pruebas de integración para descubrir bugs que no pudimos cubrir con pruebas unitarias es ignorar un problema más básico: que nuestras pruebas unitarias todavía pueden mejorarse, y que al hacerlo mejoramos la calidad de todo el proyecto.
-
Invitado
PermalinkMuchísimas gracias por traducir mi artículo en español ! Claro que no sería posible que yo lo traduzca mi mismo : como pueden ver, lo escribo así malo !<br /><br />Espero que Uds van a continuir a leer mis artículos a venir -- explico todo en lo que concierne las pruebas de integración y las razones por las cuáles son peligrosas.
-
Es un excelente artículo, muy provocador e interesante. <br /><br />Por supuesto que te estoy siguiendo en tu blog, te tengo agregado a mi lector de RSS :-)
-
Invitado
Permalink"Si podemos encontrar defectos incluso aunque nuestras pruebas pasen el 100%, y si sólo podemos tapar estos agujeros con pruebas de integración, entonces mejor escribamos pruebas de integración por todos lados".<br /><br />Eso es un olor. Si se prueba cada escenario imaginable, entonces, por supuesto, el número de casos de prueba que acaba de explotar como dice JB. Pero creo que esto sería un mal planteamiento.<br /><br />El objetivo de las pruebas de integración es probar la integración entre los componentes. Nada más. No hay millones de casos. Para probar la integración entre dos componentes, hay sólo tres casos, en general: (1) un mensaje mal-formado, (2) un mensaje bien formado que se traduce en una excepción en el consumidor, y (3) un mensaje bien formado que es procesado por el consumidor sin excepción. Podemos asumir que las pruebas unidades se cubren la functionalidad interna del componente que recibe el mensaje.<br /><br />Puede haber requisitos no funcionales que deben ser probados, por ejemplo relativos a la seguridad o el rendimiento, pero no hay ningún valor en el ejercicio de la misma lógica como las pruebas unidades.<br /><br />No creo que las pruebas de integración tiene que ser odiosas.<br /><br />El abuso de las pruebas de integración es una farsa.
-
-
Invitado
Permalinkideas tipicas de un pincher programador aislado, q piensa q lo q el codigo q escribe es infalible
-
Invitado
Permalinky tu critica es tipica de un programador que se siente superior al resto por usar lo que esta de moda sin siquiera cuestionarlo.<br />en cuanto a mi, yo tomo como un indicador de inmadurez el uso de test cases o incluso TDD, la experiencia marca que son un gastadero de tiempo y dinero y que generan -como dice el post- falsa sensacion de seguridad. digo que es una droga de nuestro medio. por esto Microsoft, entre otros, esta creando desde hace tiempo la integracion de generacion automatica de tests cases a sus herramientas...
-
Invitado
PermalinkPorque es un indicador de inmadurez? Comos e supone que se puede llegar a encarar un proyecto en el cual uno tiene unas 15 personar programando? Y al momento de subir las cosas a Produccion todo se rompe por que lo que hizo otro te esta afectando? Como podes verificar ante un gerente que lo tuyo no es lo que esta fallando? Y que pasa si hay 6 programadores que se van de la empresa? Los que vienen se tienen que fumar el codigo? Los Tests Unitarios iniciales son la mejor forma de poder irte y dejar todo funcionando, sin depender de nadie, y casi sin que haga falta saber que es lo que hace el codigo exactamente...
-
Invitado
PermalinkPense que era el unico que detestaba tdd, pero menos mal que hay unos cuantos, me parece realmente innecesario el uso de esta "metodologia" ya que no garantiza ni el "perfecto" funcionamiento de los requerimientos ni ahora tiempo (esto ultimo no se a quien se le ocurrio), lo unico bueno que le rescato es que si e sun proyecto grande pesado de compilar, hacer alguna prueba rapida nos ahorra un poco de tiempo pero no todo el desarrollo con tdd, lleva mucho tiempo de desarrollo, de aprendizaje y es una locura estructurar la cabeza utilizando esto, si todo el mundo sabe que al final se acomoda a las pruebas y no al proyecto...
Comentarios (10)