Esta es una traducción del artículo de James Carr, TDD Anti-Patterns. En dicho artículo algunos antipatrones han sido escritos por Frank Carver, Tim Ottinger, Cory Foy, Joakim Ohlrogge y Kelly Anderson. Como en otras traducciones, la terminología de dobles de tests es difícil de traducir por lo que algunos términos los he dejado en inglés. También me he tomado la libertad de añadir alguna aclaración propia.


Reciéntemente empezé a escribir un artículo sobre Antipatrones en TDD y dedicí hacer un primer borrador con los patrones más comunes que otros y yo mismo habíamos encontrado “en estado salvaje”. Entonces envié lo que había encontrado a la lista de testdrivendevelopment de yahoo y obtuve una excelente respuesta.
Como nota, ten en cuenta que esto es de momento un catálogo, méramente. Espero que se expanda ámpliamente según vamos trabajando.

Catálogo de Antipatrones en TDD

El Mentiroso
Un test completo que cumple todas las sus afirmaciones (asserts) y parece ser válido pero cuando cuando se inspecciona más de cerca muestra que realmente no esta probando su cometido en absoluto.

Setup Excesivo
Es un test que requiere un montón de trabajo para configurarlo incluso antes de que empiece. A veces se usan varios cientos de líneas de código para configurar el entorno de dicho test, con varios objetos involucrados, lo cual puede hacer difícil decir qué es lo que se está probando debido a tanto “ruido” como hay en su configuración.

El Gigante
Un test que aunque prueba correctamente el objeto en cuestión, puede contener miles de líneas y probar muchísimos casos de uso. Esto puede ser un indicador de que el sistema que estamos probando es un Objeto Dios

El Imitador
A veces usar mocks puede estar bien y ser práctico, pero otras el desarrollador se puede perder imitando los objetos que no están a prueba. En este caso un test unitario contiene tantos mocks, stubs y/o falsificaciones, que el systema a prueba ni siquiera se está probando, en su lugar estamos probando lo que los mocks están devolviendo.

El Inspector
Un test unitario que viola la encapsulación en un intento de conseguir el 100% de covertura de código y por ello sabe tanto del objeto a prueba, que cualquier intento de refactorizarlo rompería dicho test y requiere que cualquier cambio en el objeto se vea reflejado en él.

Sobras Abundantes
Es el caso en que un test unitario crea datos que se guardan en algún lugar, y otro test los reusa para sus propios fines. Si el “generador” de los datos se ejecuta despues, o nó se llega a ejecutar, el test que usa esos datos fallará por completo.

El Héroe Local
Un test que depende del entorno de desarrollo específico en que fué escrito para poder ejecutarse. El resultado es que el test pasa en dicho entorno pero falla en cualquier otro sitio. Un ejemplo típico es poner rutas que son específicas de una persona, como una referencia a un fichero en su escritorio.

El Cotilla Quisquilloso
Un test unitario que compara la salida completa de la función que se prueba, cuando en realidad sólo está interesado en pequeñas partes de ella. Esto se traduce en que el test tiene que ser continuamente mantenido a pesar de que los cambios sean insignificantes. Este es endémico de los tests de aplicaciones web. Ejemplo, comparar todo un html de salida cuando solo se necesita saber si el title es correcto.

El Cazador Secreto
Un test que a primera vista parece no estar haciendo ninguna prueba por falta de afirmaciones (asserts) pero como dicen, “el diablo está en los detalles”. El test está en verdad confiando en que se lanzará una excepción en caso de que ocurra algún accidente desafortunado y que el framework de tests la capturará reportando el fracaso.

El Escaqueado
Un test unitario que hace muchas pruebas sobre efectos colaterales (presumiblemente fáciles de hacer) pero que nunca prueba el auténtico comportamiento deseado. A veces puedes encontrarlo en tests de acceso a base de datos, donde el  método a prueba se llama, despues el test selecciona datos de la base de datos y hace afirmaciones sobre el resultado. En lugar de comprobar que el método hace lo que debe, se está comprobando que dicho método no alteró ciertos datos o lo que es lo mismo, que no causó daños.

El Bocazas
Un test unitario o batería de tests que llenan la consola con mensajes de diagnóstico, de log, de depuración, y demás forraje, incluso cuando los tests pasan. A veces durante la creación de un test es necesario mostrar salida por pantalla, y lo que ocurre en este caso es que cuando se termina se deja ahí aunque ya no haga falta, en lugar de limpiarlo.

El Cazador Hambriento
Un test unitario que captura excepciones y no tiene en cuenta sus trazas, a veces reemplazándolas con un mensaje menos informativo, pero otras incluso registrando el suceso en un log y dejando el test pasar.

El Secuenciador
Un test unitario que depende de que aparezcan en el mismo orden, elementos de una lista sin ordenar.

Dependencia Oculta
Un primo hermano del Héroe Local, un test unitario que requiere que existan ciertos datos en alguna parte antes de correr.  Si los datos no se rellenaron, el test falla sin dejar apenas explicación, forzando al desarrollador a indagar por acres de código para encontrar qué datos se suponía que debían haber.

El Enumerador
Una batería de tests donde cada test es simplemente un nombre seguido de un número, ej, test1, test2, test3. Esto supone que la misión del test no queda clara y la única forma de averiguarlo es leer todo el test y rezar para que el código sea claro.

El Extraño
Un test que nisiquiera  pertenece a la clase de la cuál es parte. Está en realidad probando otro objeto (X), muy probablemente usado por el que se está probando en la clase actual (objeto Y), pero saltándose la iteración que hay entre ambos, donde el objecto X debía funcionar en base a la salida de Y, y no directamente. También conocido como La Distancia Relativa.

El Evangelista de los Sistemas Operativos
Un test unitario que confía en que un sistema operativo específico se está usando para ejecutarse. Un buen ejemplo sería un test que usa la secuencia de nueva línea de windows en la afirmación (assert), rompiéndose cuando corre bajo Linux.

El que Siempre Funciona
Un test que se escribió para pasar en lugar de para fallar  primero. Como desafortunado efecto colateral, sucede que el test siempre funciona, aunque debiese fallar.

El Libre Albedrío
En lugar de escribir un nuevo test unitario para probar una nueva funcionalidad, se añade una nueva afirmación (assert) dentro de un test existente.

El Unico
Una combinación de varios antipatrones, particularmente El Libre Albedrío y El Gigante. Es un sólo test unitario que contiene el conjunto entero de pruebas de toda la funcionalidad que tiene un objeto. Una indicación común de eso es que el test tiene el mismo nombre que su clase y contiene múltiples líneas de setup y afirmaciones.

El Macho Chillón
Un test que debido a recursos compartidos puede ver los datos resultantes de otro test y puede hacerlo fallar incluso aunque el sistema a prueba sea perfectamente válido. Esto se ha visto comúnmente en fitnesse, donde el uso de variables de clase estáticas usadas para guardar colleciones,  no eran limpiadas adecuadamente después de la ejecución, a  menudo repercutiendo de manera inesperada en otros tests. Tambíen conocido como El huésped no invitado.

El Lento Escabador
Un test unitario que se ejecuta increíblemente lento. Cuando los desarrolladores lo lanzan les da tiempo a ir al servicio, agarrar un cigarro, o peor, dejarlo corriendo y marcharse a casa al terminar el día.

Bien, eso es todo por ahora. Me gustaría que la gente pudiera votar por los diez mejores antipatrones listados aquí para que pueda escribir más descripciones, ejemplos, síntomas y (con suerte) refactorizaciones para eliminar el antipatrón de la lista.
Si he dejado alguno fuera hacédmelo saber, cualquier patrón adicional será más que bienvenido!


En los comentarios del post de James hay algunos comentarios muy interesantes que iré traduciendo más adelante en forma de actualizaciones de este post. Los nombres que los autores eligieron para algunos de los antipatrones han sido realmente dificiles de traducir y en algunos casos (pocos casos) la traducción difiere bastante de su significado en inglés.