Buscar
Social
Ofertas laborales ES
« javaHispano probablemente estará temporalmente offline pronto por culpa del huracán Sandy | Main | Eclipse Orion 1.0: Eclipse se convierte en una aplicación web »
martes
oct302012

Los test de unidad no encuentran bugs, sólo encuentran regresiones

Este punto de vista es el que defiende Shannon Behrens en una entrada en Dzone. Según él, una de las lecciones que ha aprendido haciendo TDD es que los test no sirven realmente para encontrar bugs; esto es imposible porque la primera vez que estás escribiendo el código tú no sabes cómo ese código se va a usar, y no vas a ser capaz de crear los test adecuados.

Shannon describe su experiencia con TDD: al principio hacía muchos test que él consideraba muy buenos, y al final no tenía tiempo ni energía para hacer mucho QA, pero pensaba que no era necesario por los test. Pero después su jefe encontraba un montón de bugs en el código porque lo usaba de formas que él no había previsto.

Desde el punto de vista de Shannon, para lo que sí que es útil TDD es para evitar regresiones: una vez un bug ha sido identificado, se crea un test que lo replica, y se corrige el bug. Si hay una regresión de funcionalidad y volvemos a crear ese bug, el test nos avisará. Pero para garantizar la calidad del código, él cree que un proceso de QA manual es necesario. Citando a Knuth:

Beware of the above code. I have only tested that it works. I haven't actually tried it.

¿Qué opinais vosotros sobre este punto de vista sobre TDD? ¿Unos buenos tests pueden sustituir o no a un proceso de QA? ¿Valen los test para identificar bugs o sólo para identificar regresiones?

 

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments (10)

Desde mi punto de vista, depende bastante del momento en que se escriba el test. Si se hace correctamente y se escribe ANTES de codificar, hay mas posibilidades que luego se codifique otra cosa, ligeramente diferente, por lo que el test encuentre problemas de la especificación antes de que se lleve a detalle. Si se aplica mal el TDD y se escribe luego de codificar, en ese caso si estoy de acuerdo.

octubre 30, 2012 | Unregistered CommenterMartin

Estoy de acuerdo en que sirve para regresiones. Para detectar bugs mas bien son los tests funcionales.

Por cierto, una pregunta: igual que TDD se llama a la modalidad de escribir tests *antes* del codigo,
¿como se llamaría a la modalidad en la que escribes tests *despues* del código ?

octubre 30, 2012 | Unregistered Commenterenric

Dada una batería de regresiones para testearla, algunas de esas regresiones contienen bugs reportados por los usuarios como causantes de malos funcionamientos, y fueron añadidas a la batería.

Interesante es añadirse a la vez a la batería las regresiones que contienen bugs y regresiones corregidas sin esos dichos bugs.

Las regresiones sin corregirse sirve para que tras nuevas modificaciones de una aplicación, se espera que no se repitan los bugs "reincidentes".

octubre 30, 2012 | Unregistered Commenteranonymous

El mayor coste del software viene del mantenimiento, desde mi experiencia el más comun de los bugs y más complicado de detectar son las regresiones (si no se usan test unitarios).

Me han salvado el culo en innumerables ocasiones

octubre 30, 2012 | Unregistered Commenterdumdedum

Según mi experiencia, no es factible "codificar" todos los test (tanto por un tema de costo, como de conocimiento acerca del uso), luego siempre será necesario estar actualizandolos. Por otro lado, hay ciertos efectos "funcionales" que no necesariamente son factibles de codificar y será necesario que alguien que conozca el negocio haga los test "a mano"

octubre 30, 2012 | Unregistered CommenterK'

Hola,

yo siempre he pensado que los tests (unitarios) no sirven para detectar bugs, sino para garantizar el funcionamiento del método que pruebo. Yo tengo un test que me garantiza que si paso el parámetro "A" me devuelve "B". Después refactorizo, añado funcionalidad, o lo que sea a este mismo método, ese mismo test me garantiza que si le sigo pasando "A", me devuelve "B". Un test sirve para eso.

Incidentalmente, puede que además, detecte un bug en mi código (le pasé "A" y el método devolvió "C"). En este sentido, creo que los tests que hacía/hace el tal Shannon ese, que no sé quien es, sin haberlos visto y mal que le pese, no debían/deben de ser muy allá o no serían tests suficientes, si su jefe (¡su jefe!) le sacaba los colores cada dos por tres.

Hay quién reformula todo esto de otra manera: dado un conjunto suficiente de tests unitarios, queda descrito cómo se debe comportar el API (o el método que para el caso viene a ser lo mismo). Los fans del BDD lo llaman "given/when/then", aunque para mi no es algo específico de BDD, puede/debe/me parece un enfoque muy adecuado para el desarrollo tests unitarios.

Un conjunto de tests unitarios suficientes es una "malla de seguridad" que garantiza el comportamiento de mis métodos durante todo su ciclo de vida. También sirven para medir el impacto de introducir un cambio en el API: si lo hago y fallan el 85% de los tests unitarios asociados, introducir ese cambio va a implicar mucha más pupita que si fallan sólo el 5%.

saludos,
pendro

octubre 30, 2012 | Unregistered CommenterPerry Mason

Ay! se me olvidó comentar (lo que tienen los apretones, que no puedes decir todo lo que piensas) el testing unitario NO va a resolver todos tus problemas y como dice el amiguete Shannon tal vez otra persona que haga un análisis manual de tu código, con ojos no libídinosos, vea cosas que a ti se te han pasado por alto.

El testing unitario es una herramienta y sirve para lo que sirve, que es garantizar el comportamiento de un método, no para evitar o detectar bugs.

Para no tener bugs, pues probar, revisar, pair programming, pruebas de integración y todas esas cosas que en el 95% de las cárnicas perdón consultoras se considera un lujo.

pendro,
sent from my mobile, downloading "pretzels", if you know what I mean (o sea cagando)

octubre 30, 2012 | Unregistered CommenterPerry Mason

Los tests sirven para especificar el funcionamiento del código. El que escribe el código sí que sabe qué debe hacer y cómo hay que llamarlo. Y precisamente para eso escribe el test, para explicar cómo hay que usarlo.

Si alguien llama al código de una forma no indicada por el test y el resultado no es el esperado, no debe extrañarse ni quejarse. No es un bug. Es un mal uso del código.

octubre 30, 2012 | Unregistered CommenterDomingo

Yo no diría que el principal beneficio de TDD es que el código tenga tests. Es que, desde el primer momento, sea testeable.

Esta condición implica que, normalmente, el código resultante tendrá una mejor calidad (objetos más simples con responsabilidades mejor asignadas). De todas formas, para generar código y/o tests de calidad necesitas ingenieros de calidad y tiempo de calidad. Con lo que, por mucho TDD que apliques, si la gente que lo hace no tiene un cierto nivel puede resultar un pufo de mucho cuidado.

noviembre 2, 2012 | Unregistered Commenterxavi.f

Los test "sólo" sirven para demostrar que el código funciona no para encontrar bugs. TDD no es una técnica de QA es una técnica de desarrollo, si se sigue el proceso de TDD (test-code-refactor, no olvidarse del ultimo!) la calidad del código aumenta dramaticamente, un código más limpio por lo general contiene menos bugs y lo que quiza es más importante, los bugs que se presentan son mucho más faciles de resolver.

Yo empece ha practicar TDD, o mejor dicho empece haciendo Test After if Ever (este es el nombre que más me gusta para la técnica de hacer los test despues que antes preguntaba alguien jeje), y poco a poco empece ha hacer los test primero y después llego un momento en el que para mi lo natural es hacerlo así y si no tengo un test fallando no soy capaz de escribir código tranquilo. Pero yo no lo considero una técnica de QA, mi código sigue teniendo bugs, a veces en partes de UI dificiles de testear, a veces porque el bug no es que el código escrito sea incorrecto sino que falta código para comprobar esta o aquella condición que en un primer momento se te paso.

Un proceso de pruebas funcionales es necesario, ahora, este proceso puede ser manual o automatico, si se puede automatizar el ahorro de costos en el medio/largo plazo es evidente. El ideal seria que se hicieran pruebas funcionales (no sólo unitarias) también antes que el código (enfoque más BDD), el problema que yo me encontrado intentando esta aproximación es que a veces las tecnologías para probar desde el UI son una autentica pesadilla y rompen todo tu "flow" de desarrollo (selenium y similares). Si estas haciendo un API entonces no tienes UI y es todo mucho más facil.

Dependiendo del caso me puede parecer razonable que el equipo de desarrollo trabaje haciendo TDD y posteriormente alguien escriba test funcionales para garantizar regresión y además se realize exploratory testing manualmente al menos de las ultimas funcionalidades relacionadas.

Me inclino un poco más por la linea en la que esta james shore: http://www.infoq.com/news/2010/04/dont-automate-acceptance-tests , aunque por supuesto todo depende de muchos factores como el tipo de proyecto, la experiencia del equipo, la criticidad y el costo de los fallos (no es lo mismo una web que un proyecto para la NASA). Hay que conocer todas las opciones y decidir la estrategia de desarrollo y QA más adecuada para cada caso, no me gustán las opiones "absolutas" el mundo del desarrollo es muy amplio y nos enfrentamos a problemas que hay afrontar no siempre del mismo modo.

noviembre 2, 2012 | Registered Commenteralfredocasado

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>