¿Cuándo una prueba deja de ser unitaria?

Estoy en Bruselas asistiendo a un Train The Trainers para la nueva certificación Professional Scrum Developer creada por Ken Schwaber, uno de los padres de Scrum de la mano con Microsoft (hay una versión para Java también). La formación la está impartiendo Richard Hundhausen, viejo conocido de la comunidad en torno VSTS y TFS.

Hace un tiempo mandó un correo a una lista interna de MVPs y desarrolladores de Microsoft lanzando una cuestión muy interesante ¿Cuando una prueba unitaria se deja de considerar unitaria?. El problema es que no hay una respuesta clara para esta pregunta, pero lo bueno es que esto puede generar un debate muy interesante. Hoy he aprovechado que le tenía a mano para preguntarle si le importaba que usase las figuras de su correo para plantear esta misma cuestión en mi blog y en esas estoy.

Quiero lanzar las siguientes cuestiones:

¿De los siguientes ejemplos cuales son pruebas unitarias para tí?.
¿Si no son pruebas unitarias que tipo de pruebas son? integración, aceptación, caja negra, caja blanca… ¿cómo las etiquetarías?.

Ejemplo 1 – Muy probablemente todos coincidamos en que esto es una prueba unitaria. Sin lugar a dudas ¿no?.

clip_image001[7]

Ejemplo 2 – ¿Y si el método público llama a uno privado? ¿Sigue esto siendo un test unitario?

clip_image002[5]

Ejemplo 3 –¿Y si se llama a otro método público se convierte el test en un test de integración?

clip_image003[5]

Ejemplo 4 – ¿Esto es un test de integración? o sigue siendo un test unitario.

clip_image004[6]

Ejemplo 5 – ¿Un test unitario se convierte en un test de integración si cruzamos las fronteras del assembly bajo test?

clip_image005[4]

Ejemplo 6 – ¿Y si llamamos a una base de datos o a un servicio web? ¿Es esto un test unitario para vosotros? o es un test de sistema.

clip_image006[4]

¿En definitiva cuando una prueba unitaria deja de ser una prueba unitaria y pasa a ser otra cosa?

Para mi todos los casos son casos de pruebas unitarias, de diferente naturaleza, pero pruebas unitarias al fin y al cabo.

Poniéndome purista podría admitir que el ejemplo 6 no lo sea. Pero ya he dejado claro anteriormente que una cosa que quiero poder hacer con mis test es ejecutarlos contra la base de datos (no siempre, pero si cuando me convenga, hago posible gracias a inversión de control e inyección de dependencias).

El ejemplo 5 también me plantea dudas, pero si consideramos que no es una prueba unitaria ¿deberíamos entonces sistemáticamente mockear todas las llamadas hacia afuera de nuestro assembly? ¿Incluidas también las llamadas al framework?.

Espero vuestras opiniones.

7 comentarios sobre “¿Cuándo una prueba deja de ser unitaria?”

  1. Para mí todo depende del grado de enfermedad… quiero decir purismo que alcance cada uno al hacer sus pruebas.

    Para mí un test unitario se basa en probar la mínima cantidad de código, cuanto más grande es el código probablemente más complejidad ciclomática tenga, no hablemos ya de si incluimos llamadas a métodos.

    Cruzar o no la frontera del assembly no tiene tanta importancia como el hecho de acceder al entorno de ejecución (Ficheros, BBDD, SW).

    Está claro que tenemos que probar las cosas contra la implementación real, pero como tu has dicho eso se puede hacer sin mucha dificultad usando un IoC.

    En cuanto a los métodos privados es un tema peliagudo, con typemock los puedes mockear, con moles supongo que también. En cualquier caso puedes crear un metodo accesor de estos que te crea MSTest. Pero como he dicho depende del grado de purismo de cada 1. Yo en caso de no mockear el método privado por lo menos lo probaría y verificaría que su comportamiento es correcto para los casos en que es llamado por mis pruebas del método público. Así tendría la certeza de que si mi método público falla, no lo hace por culpa del privado. (Y los ejecutaría en orden como un Ordered Test).

    En resumen, toda práctica tiene su overhead, y todo es hacer un balance entre los beneficios que te aporta y el tiempo que consume.

    También hay que decir que muchas veces testeamos todo el sistema por igual, y eso en cierto modo es también un error, o mejor dicho una mala administración de nuestros recursos, al igual que priorizamos los requisitos por valor de negocio de nuestro cliente, quizás deberíamos priorizar la exhaustividad de nuestras pruebas en función del valor de negocio del requisito que ayudan a implementar. Al fín y al cabo no es tan importante que falle un pequeño detalle como que falle un punto crítico del sistema.

    Un saludo

  2. Rodrigo, perdona que no sea sobre la temática del post… pero donde puedo conseguir información sobre esa certificación.

    Se me ha caido la baba y se me han peusto los dientes largos.

  3. @javier interesante comentario, comparto todo lo que comentas. Lo único que yo no haría es confiar en el orden de los tests o exigir un orden determinado de ejecución. El nombre del test debe ser suficiente para identificar que prueba un test y por tanto poder detectar si fallo la parte pública o la privada o lo que sea…

    @Juan: Es probable que si hay demanda suficiente realicemos un curso de certificación en Español para la vuelta de verano. Estamos estudiando el asunto. Escribiré más sobre el tema cuando termine el curso que estoy recibiendo. De momento puedes encontrar más información en http://scrum.org.

    Un saludo.

  4. Muchas gracias Rodrigo.

    También muchas gracias por la pista de scrum.org. Me estoy bajando la beta de la plantilla de tfs2010.

    Interesantísimo.

  5. Lo de pruebas de aceptación dentro de las unitarias es algo que me resisto a ver. Lo demás lo veo igual todas son PU.. para mi la pregunta es ¿cuando caja negra y cuando caja blanca? ¿Cuales son mejores en cada caso?

  6. Es dificil categorizarlas. En nuestro producto llamamos pruebas de integración a las pruebas que incluyen servicios del dominio y repositorios reales (no mocks) que atacan directamente a la base de datos.
    Si bien tenemos test que prueban a los servicios de manera aislada, encontramos nuestros llamados test de integración son los más útiles para hacer TDD.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *