sintesis

¿Por qué?

  • ¿Cómo pruebo un SUT con técnicas de Caja Negra

    • cuya entrada depende de un DOC o

    • cuya salida va hacia un DOC?

  • no está implementado, o

  • está en producción y no se puede alterar, o

  • es un componente externo a la prueba unitaria, o

  • es muy lento, o

  • …​?

  • ¿Cómo pruebo un SUT con técnicas de Caja Blanca?

¿Qué?

  • Los dobles son los objetos que imitan el comportamiento de objetos reales de una forma controlada en el entorno de prueba.

    • Por ejemplo:

      • Al igual que los ingenieros de automóviles utilizan un muñeco, crash dummy, cuando simulan un accidente para estudiarlo y evitar pruebas con personas reales. Luego entregan un coche que se conducirá por una persona real

      • Directores de cine usan “dobles” para las tomas que entrañan riesgos para el actor principal … pero cuidado!?! a producción entregan la película con las escenas del “doble”?!? No sería una buena analogía

dummies

¿Para qué?

  • Prueba lenta: porque el DOC realiza cálculos extensivos o accesos a memoria secundaria o a base de datos, …

  • Prueba errática: porque el DOC suministra al SUT valores de entrada “descontrolados” (aleatório, hora, señal de sensor, …)

  • Prueba interventora: porque el DOC es una interfaz de usuario, como en MVC, cuando el SUT es el controlador.

  • Prueba con Sermón de Preparación: porque la construcción del DOC es un esfuerzo superior a la configuración de un doble

  • Prueba con Dependencia Oculta: porque el DOC es parte de otro componente, por ejemplo, librería de acceso a otro servidor vía tcp/ip, o no debe cambiar su estado por ejemplo, un servicio de correo y no se desea desplegar un servicio de correo alternativo

  • DOC no está disponible: porque no está finalizada por parte de un compañero, o es posterior en desarrollo es top/down, TDD outside-in, …​ o porque están con una versión anterior

    • …​ la gran desventaja es que son frágiles al depender de la implantación

¿Cómo?

Dobles en el Ciclo de Vida

height32

height32

Test Last Development

  • Una vez diseñada la clase Z, se implementa

  • Una vez implementada la clase Z, se prueba

height32

height32

  • Una vez diseñada la clase Y, se implementa

  • Una vez implementada la clase Y, se prueba

    • Se dobla la clase Z por algún motivo: lentitud, …​

height32

height32

  • Una vez diseñada la clase X, se implementa

  • Una vez implementada la clase X, se prueba

    • Se dobla la clase Y por algún motivo: lentitud, …​

height32

height32

Test First Development

  • Una vez diseñada la clase Z, se prueba

  • Una vez probada la clase Z, se implementa

height32

height32

  • Una vez diseñada la clase Y, se prueba

  • Una vez probada la clase Y, se implementa

    • Se dobla la clase Z por algún motivo: lentitud, …​

height32

height32

  • Una vez diseñada la clase Z, se prueba

  • Una vez probada la clase Z, se implementa

    • Se dobla la clase Z por algún motivo: lentitud, …​

height32

height32

Test Driven Development: Inside-out

  • Se prueba diseñando la clase Z

  • Una vez probada la clase Z, se implementa

height32

height32

  • Se prueba diseñando la clase Y

    • Se dobla la clase Z por algún motivo: lentitud, …​

  • Una vez probada la clase Y, se implementa

height32

height32

  • Se prueba diseñando la clase X

    • Se dobla la clase Y por algún motivo: lentitud, …​

  • Una vez probada la clase X, se implementa

height32

height32

Test Driven Development: Outside-in

  • Se prueba diseñando la clase X

    • Se dobla diseñando la clase Y por obligación

  • Una vez probada la clase X, se implementa

height32

height32

  • Se prueba la clase Y

    • Se dobla diseñando la clase Z por obligación

  • Una vez probada la clase Y, se implementa

height32

height32

  • Se prueba la clase Z

  • Una vez probada la clase Y, se implementa

height32

height32

Comparativas de Pruebas con y sin Dobles

Sin dobles Con dobles
  • Son Pruebas Unitarias y de mini-Integración de Caja Negra, porque ejecutan el SUT y/o todos los DOC primarios, secundarios, …​, no solo una clase, independientemente de la implantación del SUT

  • Son Pruebas Unitarias puras de Caja Blanca, porque ejecutan el SUT pero ningún DOC real, sino llamadas al doble, por tanto dependiente de la implantación del SUT

  • Facilita que un SUT se ejercite con su prueba y forme parte del ejercicio de las pruebas de otro SUT que tiene al primero como su DOC, permitiendo detectar nuevos fallos, particularmente probando áreas o entradas que no se planteó en la prueba del SUT.

  • Aisla el SUT pero no facilita que un SUT se ejercite con su prueba y forme parte del ejercicio de las pruebas de otro SUT que tiene al primero como su DOC, permitiendo detectar nuevos fallos, particularmente probando áreas o entradas que no se planteó en la prueba del SUT.

Un cambio de implantación, rediseño por refactoring, optimización, …​,

  • no provoca una oleada de pruebas fallidas, porque no se basan en su implantación.

  • puede provocar una oleada de pruebas fallidas, porque se basan en la interacción interna entre el SUT y el DOC.

Un cambio de requisitos de funcionalidad

  • puede provocar una oleada de pruebas fallidas. Para contener esta oleada respecto a la creación, se contemplan todos los principios y patrones de diseño

    • Por ejemplo, el patrón Builder para centralizar la creación de objetos acoplada al constructor de una clase

  • NO puede provocar una oleada de pruebas fallidas. Pero se corre el riesgo de que las expectativas de los pruebas con dobles sean incorrectas, resultando en pruebas unitarias que están en verde pero que enmascaran errores inherentes!!!.

Tipos de Dobles

  • Todos los dobles:

    • Debe implementar el mismo interfaz que el DOC.

    • En la clase de prueba se debe definir qué métodos del objeto DOC real queremos que simule el doble, indicando para cada uno de ellos cuál es la respuesta esperada cuando reciba unos parámetros predeterminados. O sea, la respuestas del doble debe ser la misma que esperamos que devuelva el objeto real con la misma entrada cuando esté disponible.

    • Al ejecutar la prueba, cuando el SUT que queremos probar llame a un objeto real que no esté disponible por el criterio que sea y que hemos simulado con el doble, esa llamada será “interceptada” por el doble y devolverá la respuesta que hayamos definido.

Resguardo, Stub

  • Son dobles pre-programados con valores de salida “enlatados” a las lamadas realizadas desde el SUT con sus entradas y, por lo general, no responden en absoluto a nada fuera de lo que está configurado en la prueba.

    • También pueden grabar información sobre las llamadas tal como una pasarela de email que recuerda qué mensajes envió o quizás sólo cómo se enviaron los mensajes.

    • Por tanto, idóneas para pruebas de Caja Negra o Estado.

Stub

Muñeco, Mock

  • Son dobles pre-programados con las expectativas de las llamadas que se espera recibir el DOC: con ciertos argumentos, un cierto número de veces, …​

    • Durante la verificación se comprueba que recibieron todas las expectativas, lanzando excepciones si reciben una expectativa no esperada.

    • Por tanto, idóneas para pruebas de Caja Blanca o Comportamiento.

Mock

Espía, Spy

  • Son stubs que además verifican la interacción entre el SUT y el DOC o son mocks que además verifican los datos de salida a través del DOC.

    • Son la mezcla de stubs y mocks, de Caja Negra y Caja Blanca.

Fantasma, Dummy

  • Son dobles necesarios para rellenar en una lista de argumentos pero el ejercicio del SUT no va a colaborar con el DOC, por tanto no tiene comportamiento

Falsete, Fake

  • Son dobles que tienen una implementación real aparentando un funcionamiento correcto pero, por lo general, toman algún atajo que los hace no aptos para la producción.

    • Un falsete, fake, sería un emulador, imita el comporatmiento exterior pero no el interior, otra estructura interna! mientras que un muñeco, mock, sería un simulador, imita el comportamiento exterior y el interior, la misma estructura interna!

    • por ejemplo: una base de datos en la memoria interna, fake o mock?!?

Sintesis

sintesis

Bibliografía

Obra, Autor y Edición Portada Obra, Autor y Edición Portada
  • xUnit Test Patterns: Refactoring Test Code

    • Gerard Meszaros

    • Addison-Wesley Educational Publishers Inc; Edición: 01 (21 de mayo de 2007)

xUnitTestPatternsRefactoringTestCode

  • Effective Unit Testing

    • Lasse Koskela

    • Manning Publications Company; Edición: 1 (16 de febrero de 2013)

EffectiveUnitTesting

  • The Art of Software Testing

    • Glenford J. Myers

    • John Wiley & Sons Inc; Edición: 3. Auflage (16 de diciembre de 2011)

TheArtofSoftwareTesting

  • Pragmatic Unit Testing in Java with JUnit

    • Andy Hunt, Dave Thomas

    • The Pragmatic Programmers (1674)

PragmaticUnitTestinginJavawithJUnit

  • Testing Computer Software

    • Cem Kaner,Jack Falk,Hung Q. Nguyen

    • Wiley John + Sons; Edición: 2nd (12 de abril de 1999)

TestingComputerSoftware

  • Diseno Agil con TDD

    • Ble Jurado, Carlos

    • Lulu.com (18 de enero de 2010)

DisenoAgilconTDD

  • Test Driven Development

    • Kent Beck

    • Addison Wesley; Edición: 01 (8 de noviembre de 2002)

TestDrivenDevelopment

  • Growing Object-Oriented Software, Guided by Tests

    • Steve Freeman

    • Addison-Wesley Professional (12 de octubre de 2009)

GrowingObjectOrientedSoftware,GuidedbyTests

  • How Google Tests Software

    • James A. Whittaker,Jason Arbon,Jeff Carollo

    • Addison-Wesley Educational Publishers Inc; Edición: 01 (2 de abril de 2012)

HowGoogleTestsSoftware

  • Pragmatic Project Automation: How to Build, Deploy, and Monitor Java Apps

    • Mike Clark

    • The Pragmatic Programmers (1900)

PragmaticProjectAutomation

Ponente

  • Luis Fernández Muñoz

setillo

  • Doctor en Inteligencia Artificial por la UPM

  • Ingeniero en Informática por la UMA

  • Diplomado en Informática por la UPM

  • Profesor Titular de ETSISI de la UPM