Introducción a TDD
Enfoque de la Charla Presentar un ejemplo de principio a finde una funcionalidad de un proyecto.Sin profundizar en las he...
Objetivos de la charla-- Introducir TDD como una alternativa viable aldesarrollo tradicional.-- Crear cierta inquietud por...
¿Que es TDD?Practica de desarrollo de softwareTest First + Refactor
¿Que ventajas trae TDD aldesarrollador?• Confianza en el funcionamiento.• Foco en el desarrollo.• Código mas limpio. (Buen...
Realizar el menor diseño posibleantes de empezar. Solo lo necesario(Generalmente la Infraestructura dela aplicación). Los ...
El ciclo de TDDRefactoRefactorrEscribir unEscribir untest Unitariotest Unitarioque falleque falleHacer que elHacer que elt...
Conocido como el cicloROJO->VERDE->REFACTOR
¿Cuanto tiempo pueden estar lostests en rojo?- - Test Unitarios deben pasar cuanto antes.- - Test funcionales tardarán mas...
¿Cuanto del código probar?- - Probar TODO lo que tenga sentidoprobar.- - No probar lo trivial.- - Spikes paraThird Party.-...
¿Como comenzar?.- - Escoger la funcionalidad (feature)mas pequeña posible que laaplicación deba cumplir.- - Luego ir escog...
Nuestro ejemplo.SituaciónInicialSituaciónFinal
Iteración 0
¿Que es un test de aceptación otest funcional?Nos ayuda a definir exactamentela funcionalidad que queremoshacer. Un test d...
 No debe conocer los objetosinternos del sistema. Debe reaccionar ante eventosque se produzcan en la capa"visible" (GUI,...
Prueba la interacción entre distintoscomponentes del sistema, o entre elsistema y componentes externos. Porejemplo con la ...
Definimos el Test Funcional.Selenium
Definimos el Test Funcional.Selenium. Permite ejecutar TestsDirectamente sobre la interfaz deusuario HTML, sobre un navega...
Definimos el Test Funcional.Este Test podrá estar sin pasarpor mucho tiempo. Nos sirvecomo guía de la funcionalidadfinal q...
Prueba comportamientos enaislamiento TOTAL respecto alresto del sistema. Prueba una ysolo una caracteristica sin quelos de...
El primer Test Unitario. La primera abstracción que se nos ocurre es una Cuenta. En la que podemosdepositar y sacar diner...
El primer Test Unitario.Hacemos el test compilar. Para eso creamos la clase Account y los métodosnecesarios.
El primer test unitario.El Test Compila.
El primer Test UnitarioBarra roja
El primer Test unitario. Implementación Falsa VS Implementación obvia. Pasamos el Test con implementación falsa.
Realizamos otro test que nos obligue a sustituir la implementación falsa. Esto esTriangulación en TDDEl primer Test unitar...
Cambiamos la implementaciónEl primer Test unitario.
La barra verde nuevamenteEl primer Test unitario.
 Cuando se sepa claramente laimplementación obvia, aplicarla. No es necesario siempre dar los pasosmas pequeños posibles...
Es importante hacer tests parasituaciones que esperamosproduzcan un error.Probando los fallos.
Probando los fallos.Hemos creado por TDD lo siguiente en AccountTest y Account parael retiro de dinero.Sin embargo como re...
Probando los fallos.Con esto decimos que esperamos que al producirse estasituación (Rerirar mas de lo que tenemos), se ele...
Probando los fallos.Creamos la excepción. Nuestro Test Compila
Probando los fallos.Ejecutamos el Test. Barra Roja
Añadimos la implementación obvia. Ejecutamos. Barra Verde.Probando los fallos.
Probando los fallos.Refactorizamos con un sencillo Extract Method. Ejecutamos. Barra Verde.
Continuando con Account.Soporte de DivisasLa siguiente caracterisitac que deben soportar nuestrascuentas, es que pueden es...
Continuando con Account.Soporte de Divisas.Cuando uno crea un Test, la idea es imaginar el APImas correcto de lo que estam...
Hacemos los cambios necesarios aAccount para que compile y damos lasolución obvia. Nuestros Tests anterioresya no compilan...
Es muy importante ejecutar TODA la suite deTests cuando se hacen cambios yrefactorizaciones. Ya que aunque en el casoanter...
RefactorizaciónUno de los mas importantes "Code Smells", esel hecho de utilizar Strings para representarcosas que son mas ...
Continuando con Account.Soporte de Divisas.
 Añadimos también, por comodidad un constructor que apartede la divisa, se le pueda enviar también el balance inicial.Con...
Probando el servicio detransferencia.Dejando Account a un lado, considerandolo terminado, noscentramos en el servicio de t...
El primer test que se nos ocurre es hacer una transferenciaentre 2 cuentas con la misma divisa.Probando el servicio detran...
El código anterior es lo primero que senos ocurre realizar. Sin embargo,viendo la interfaz del método transfer,los parámet...
Decidimos que un mejor diseño es encapsular la transferenciaes su propio objeto y pasar este objeto al metodo transfer.Pro...
La TransferOperation es mucho mas especifica. Creamos lasclases que nos faltanProbando el servicio detransferencia.
Ejecutamos nuestro Test. Barra Roja!!.Probando el servicio detransferencia.
Haciendo una inspección de que puede estar fallando, nos damoscuenta que el error no esta en el servicio, ni en el Test.. ...
Prueba de Regresión. Se reporta un Error(Bug) por una funcionalidad dada por cerraday que por falta de input no se hizo el...
Vamos a AcountTest. y agregamos un Test para el error quehemos obtenido. Barra RojaProbando el servicio detransferencia.
Vamos a la clase Account e implementamos de forma correcta(que al menos pase este test que es lo que entendemos porcorrect...
Ejecutamos nuestro Test AccountTest. Barra Roja otra vez.Probando el servicio detransferencia.
Vemos que ahora el balance es null en deposit cuando aun nose ha depositado nada. La ejecución de los Tests, siempre va ac...
Regresamos al punto donde realmente estabamos. EnTransferTest. Lo ejecutamos. Barra Verde.Probando el servicio detransfere...
Refactoring.La forma de construir la TransferOperation no es del todo agradable. sustituimos lossetters actuales por un se...
Cambiamos el codigo de TransferOperation,Ejecutamos el Test, Barra Verde.
Transferencias entre 2 monedas distintas.Diseñamos nuestro Test. Primera aproximación.Sin factor de conversión. Barra Verd...
Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximaciónProbando el servicio detransferencia.
Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximacion. Hacemoscompilar el codigo. Ejecut...
Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximación.Implementamos.Probando el servicio...
Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximación. Ejecutamos los Tests. Barra RojaP...
Transferencias entre 2 monedas distintas. Se arregla el bug quese acaba de introducir. Ejcutamos los Test. Barra Verde. (O...
Transferencias entre 2 monedas distintas. Refactorización SRP.Necesitamos otro servicio, Currency Service que se ocupe de ...
Creamos la implementación extrayendo una clase nueva deTransferServiceImpl.
 Incluimos la dependencia en TransferService para que utilice la nuevadependencia.
Ejecutamos CurrencyTest. Barra Verde. Sin emabrgo luego deuna amplia refactorización como la hecha es necesario ejecutarto...
Transfer Test se ha roto con larefactorización, ya que se ha incluidouna nueva dependencia que nohabiamos considerado cuan...
 En el caso anterior en realidad se debíahacer el test antes de añadir ladependencia a la claseimplementación. Siempre s...
Mock Objects Introduciremos un Mock para ladependencia. ¿Qué es un Mock Object?
Mock Object. Mock hecho a mano
JMOCKNos permite con un lenguajeespecifico de dominio definirDobles de objetos paranuestros Test, y establecer lasexpectat...
Mock con Jmock. Y expectativas.Ejecutamos todos los tests. Barra verde
El uso de mocksEl uso de mocksSe puede establecer su necesidad encualquiera de los dos tiempos dediseño. Escribir el Test,...
Refactorizando CurrencyService. Esemapa de mapas es muy lioso. Se nosocurre mover la responsabilidad desaber el rate de ca...
 Para hacer esto decidimos tambiénconversión establecer Rates a una divisaúnica y utilizar esta para los cambios.Usamos e...
Escribimos los Tests (En realidad se escribieron 1 a1 estos tests). Y Ejecutamos, Barra Roja.
Implementamos
Ejecutamos los tests. Green BarRefactorizamos CurrencyService
Persistiendo los cambiosPersistiendo los cambios. Servicio de persistencia de cuentas. Mock del Dao en Las transferencias....
Persistiendo los cambios - Diseñamos el Test con lasdependencias en Mente. - Nos damos cuenta de la necesidad deun ident...
Lo hacemos compilar. Implementamos en account service.Ejecutamos el test. Barra Verde.
Test Driving el DAO. Test deIntegración.Ahora haremos la implementacióndel DAO guiado por tests.Exactamente igual que como...
Utilizaremos el poderoso Spring Test Context para las pruebas deintegración. (Las siguientes pruebas se hicieron 1 a 1).
Implementamos (En realidad lo anteriorse hizo test a test. Pero para recortar loponemos todo de hecho con la primeraejecuc...
En algunos casos, los tests de integración son bastante maslentos que los tests unitarios como vemos.Ejecutamos la suite e...
Persistiendo lastransferenciasEl servicio de transferencias ahora mismo nopersiste los datos. Debemos añadir esto a nuestr...
Ejecutamos. Barra Verde
TDD el controlador.Se basa en los mismos procedimientos queel probar las otras capas. Centrarnos en lafuncionalidad requer...
TDD El controlador.Lo hacemos compilar.Ejecutamos. Barra Roja
TDD el controladorImplementamos. Ejecutamos el Test. Barra Verde. En principiono hay refactorización que hacer.
TDD el controlador. El submit del formularioMocking HttpServletRequest.
TDD el controlador. Implementamos. Barra Verde.
Ejecutamos la Suite Entera deTests. Barra Verde.
El test funcional. Creamos las JSPs requeridas segun nuestros Test, nuestrocontroller y nuestro conocimiento de Spring MVC...
transferResult.jsp
Todo dentro del Test El Test funcional idealmente es capazde iniciar todo su entorno. En nuestrocaso iniciamos el Tomcat.
Utilizamos Cargo para controlar el servidor.
Preparando para el Test Funcional
Las 2 fases del BUILD
Ejecutando el Test Funcional. Incluimos Un setup Completo en el test que inicia elservidor tomcat.
Ejecutamos la Suite Entera Incluyendo Funcionales
Las 2 Fases del BUILD En un entorno de integración continua. Mvn test: Ejecuta los Tests unitarios, seejecutara en cada ...
Revisando el Code Coverage Cobertura. Mvn site Mas que medir la cobertura porporcentaje. Estar conscientes de quehemos ...
Reporte del EjemploPACKAGE CLASES LINE COVERAGEALL PACKAGES 16 75%ORG.PT.TDD 1 92%ORG.PT.TDD.DAO 2 75%ORG.PT.TDD.DOMAIN 3 ...
Cobertura
Cobertura
Conclusiones-- TDD nos ayudan a mantener el foco de loque queremos desarrollar.-- TDD nos sirve como red de seguridad para...
Bibliografía
Preguntas
Seminario de Test Development Driven
Seminario de Test Development Driven
Seminario de Test Development Driven
Seminario de Test Development Driven
Seminario de Test Development Driven
Seminario de Test Development Driven
Seminario de Test Development Driven
Seminario de Test Development Driven
Seminario de Test Development Driven
Upcoming SlideShare
Loading in...5
×

Seminario de Test Development Driven

201

Published on

Seminario de introducción a Test Driven Development organizado por Paradigma Tecnológico y javaHispano. El seminario fue impartido por Carlo Scarioni el 23 de Abril 2010
Mas info: http://www.paradigmatecnologico.com/historico/seminario-de-test-development-driven/

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
201
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
13
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Seminario de Test Development Driven

  1. 1. Introducción a TDD
  2. 2. Enfoque de la Charla Presentar un ejemplo de principio a finde una funcionalidad de un proyecto.Sin profundizar en las herramientasutilizadas. El objetivo es clarificar elproceso de TDD.
  3. 3. Objetivos de la charla-- Introducir TDD como una alternativa viable aldesarrollo tradicional.-- Crear cierta inquietud por profundizar mas enel tema.-- Exponer las ventajas que TDD tiene para eldesarrollador.-- Explicar paso a paso como afrontar unafuncionalidad con esta práctica.
  4. 4. ¿Que es TDD?Practica de desarrollo de softwareTest First + Refactor
  5. 5. ¿Que ventajas trae TDD aldesarrollador?• Confianza en el funcionamiento.• Foco en el desarrollo.• Código mas limpio. (Buenas practicas de desarrollo ypatrones).• Menos Bugs y mas localizados.• Documentación del código con los Tests.• Menos reinicio del servidor para probar.
  6. 6. Realizar el menor diseño posibleantes de empezar. Solo lo necesario(Generalmente la Infraestructura dela aplicación). Los test guiarán eldiseño.El ciclo de TDD
  7. 7. El ciclo de TDDRefactoRefactorrEscribir unEscribir untest Unitariotest Unitarioque falleque falleHacer que elHacer que eltest pasetest paseEscribir un TestFuncional Quefalle
  8. 8. Conocido como el cicloROJO->VERDE->REFACTOR
  9. 9. ¿Cuanto tiempo pueden estar lostests en rojo?- - Test Unitarios deben pasar cuanto antes.- - Test funcionales tardarán mas en pasar. Y estarán enun ciclo distinto del BUILD.- - Nunca se subirán tests que fallan al repositorio decódigo fuente.- - Solo se desarrolla funcionalidad cuando exista un Testfallido que lo requiera.
  10. 10. ¿Cuanto del código probar?- - Probar TODO lo que tenga sentidoprobar.- - No probar lo trivial.- - Spikes paraThird Party.- - Cobertura.
  11. 11. ¿Como comenzar?.- - Escoger la funcionalidad (feature)mas pequeña posible que laaplicación deba cumplir.- - Luego ir escogiendofuncionalidades de nuestro ProductBacklog.
  12. 12. Nuestro ejemplo.SituaciónInicialSituaciónFinal
  13. 13. Iteración 0
  14. 14. ¿Que es un test de aceptación otest funcional?Nos ayuda a definir exactamentela funcionalidad que queremoshacer. Un test define QUEqueremos hacer, si importarrealmente el COMO.
  15. 15.  No debe conocer los objetosinternos del sistema. Debe reaccionar ante eventosque se produzcan en la capa"visible" (GUI, LOG, etc).Usualmente haciendo un pollpara ver si hay cambios.Test Funcional
  16. 16. Prueba la interacción entre distintoscomponentes del sistema, o entre elsistema y componentes externos. Porejemplo con la Base de Datos, Con elsistema de ficheros, etc.Test Integración
  17. 17. Definimos el Test Funcional.Selenium
  18. 18. Definimos el Test Funcional.Selenium. Permite ejecutar TestsDirectamente sobre la interfaz deusuario HTML, sobre un navegador enparticular. Para esto la aplicación debeestar iniciada. El proceso de iniciar laapliciación debe ser automático, previoa la ejecución de los test, y terminadoluego.
  19. 19. Definimos el Test Funcional.Este Test podrá estar sin pasarpor mucho tiempo. Nos sirvecomo guía de la funcionalidadfinal que queremos conseguir.
  20. 20. Prueba comportamientos enaislamiento TOTAL respecto alresto del sistema. Prueba una ysolo una caracteristica sin quelos demas elementos delsistema afecten su ejecución.Test Unitario
  21. 21. El primer Test Unitario. La primera abstracción que se nos ocurre es una Cuenta. En la que podemosdepositar y sacar dinero. Hacemos el test para depositar dinero
  22. 22. El primer Test Unitario.Hacemos el test compilar. Para eso creamos la clase Account y los métodosnecesarios.
  23. 23. El primer test unitario.El Test Compila.
  24. 24. El primer Test UnitarioBarra roja
  25. 25. El primer Test unitario. Implementación Falsa VS Implementación obvia. Pasamos el Test con implementación falsa.
  26. 26. Realizamos otro test que nos obligue a sustituir la implementación falsa. Esto esTriangulación en TDDEl primer Test unitario.
  27. 27. Cambiamos la implementaciónEl primer Test unitario.
  28. 28. La barra verde nuevamenteEl primer Test unitario.
  29. 29.  Cuando se sepa claramente laimplementación obvia, aplicarla. No es necesario siempre dar los pasosmas pequeños posibles. Si la implementación obvia resulta noser tan obvia, y al implementarla lostest fallan. Hacer los pasos maspequeños posibles.El primer Test unitario.
  30. 30. Es importante hacer tests parasituaciones que esperamosproduzcan un error.Probando los fallos.
  31. 31. Probando los fallos.Hemos creado por TDD lo siguiente en AccountTest y Account parael retiro de dinero.Sin embargo como requerimiento tenemos que no podemos dejaruna cuenta a un numero negativo. Por tanto hay que comprobar queesto no se pueda dar.
  32. 32. Probando los fallos.Con esto decimos que esperamos que al producirse estasituación (Rerirar mas de lo que tenemos), se eleve la excepciónWithdrawlException (Que aun no existe).
  33. 33. Probando los fallos.Creamos la excepción. Nuestro Test Compila
  34. 34. Probando los fallos.Ejecutamos el Test. Barra Roja
  35. 35. Añadimos la implementación obvia. Ejecutamos. Barra Verde.Probando los fallos.
  36. 36. Probando los fallos.Refactorizamos con un sencillo Extract Method. Ejecutamos. Barra Verde.
  37. 37. Continuando con Account.Soporte de DivisasLa siguiente caracterisitac que deben soportar nuestrascuentas, es que pueden estar en EUR, USD o GBP.Comenzamos con el TEST.
  38. 38. Continuando con Account.Soporte de Divisas.Cuando uno crea un Test, la idea es imaginar el APImas correcto de lo que estamos creando. En este casonos damos cuenta que una Cuenta DEBE tener unadivisa. Por lo que la ponemos en le constructor.
  39. 39. Hacemos los cambios necesarios aAccount para que compile y damos lasolución obvia. Nuestros Tests anterioresya no compilan (requerían constructorvacio). Cambiamos la construcción delas Accounts para el nuevo constructor.Ejecutamos los Tests. Barra verde.Continuando con Account.Soporte de Divisas.
  40. 40. Es muy importante ejecutar TODA la suite deTests cuando se hacen cambios yrefactorizaciones. Ya que aunque en el casoanterior se detectó en compilación el fallo (Lafalta de constructor). Muchas veces uncambió hará que cosas que asumiamoscomo correctas ya no lo sean. Y habrá queadaptar los Tests y el código a la nuevasolución.Continuando con Account.Soporte de Divisas.
  41. 41. RefactorizaciónUno de los mas importantes "Code Smells", esel hecho de utilizar Strings para representarcosas que son mas que texto y tienensignificado propio. En nuestro caso, el Stringque se pasa al constructor.Creamos un ENUM para representar nuestrasdivisas. Adaptamos los Tests. Barra VerdeContinuando con Account.Soporte de Divisas.
  42. 42. Continuando con Account.Soporte de Divisas.
  43. 43.  Añadimos también, por comodidad un constructor que apartede la divisa, se le pueda enviar también el balance inicial.Continuando con Account.Soporte de Divisas.
  44. 44. Probando el servicio detransferencia.Dejando Account a un lado, considerandolo terminado, noscentramos en el servicio de transferencia.Para nosotros una transferencia será sencillamente, retirar deuna cuenta, y depositar en otra.
  45. 45. El primer test que se nos ocurre es hacer una transferenciaentre 2 cuentas con la misma divisa.Probando el servicio detransferencia.
  46. 46. El código anterior es lo primero que senos ocurre realizar. Sin embargo,viendo la interfaz del método transfer,los parámetros se prestan a confusión.¿De que cuenta a que cuenta es latransferencia?Probando el servicio detransferencia.
  47. 47. Decidimos que un mejor diseño es encapsular la transferenciaes su propio objeto y pasar este objeto al metodo transfer.Probando el servicio detransferencia.
  48. 48. La TransferOperation es mucho mas especifica. Creamos lasclases que nos faltanProbando el servicio detransferencia.
  49. 49. Ejecutamos nuestro Test. Barra Roja!!.Probando el servicio detransferencia.
  50. 50. Haciendo una inspección de que puede estar fallando, nos damoscuenta que el error no esta en el servicio, ni en el Test.. sino enAccount (Podriamos hacer un mock temporal de la clase account yver que se llaman al deposit y withdrawal correctamente. Pero elservicio es muy simple y resulta obvio). Clase que habiamos dadapor terminada. Vemos que el problema está en el metodo deposit.Por no haber triangulado lo suficiente en las pruebas.Probando el servicio detransferencia.
  51. 51. Prueba de Regresión. Se reporta un Error(Bug) por una funcionalidad dada por cerraday que por falta de input no se hizo el testadecuado. Normalmente la falta de input espor requerimientos no entendidoscompletamente. En nuestro caso es que nohicimos todas las pruebas que debimos.Probando el servicio detransferencia.
  52. 52. Vamos a AcountTest. y agregamos un Test para el error quehemos obtenido. Barra RojaProbando el servicio detransferencia.
  53. 53. Vamos a la clase Account e implementamos de forma correcta(que al menos pase este test que es lo que entendemos porcorrecto) el metodo deposit.Probando el servicio detransferencia.
  54. 54. Ejecutamos nuestro Test AccountTest. Barra Roja otra vez.Probando el servicio detransferencia.
  55. 55. Vemos que ahora el balance es null en deposit cuando aun nose ha depositado nada. La ejecución de los Tests, siempre va acapturar comportamientos no deseados como este, si se hacenlos tests correctos.Corregimos Account y ejecutamos el Test. Barra Verde. Al fin.Probando el servicio detransferencia.
  56. 56. Regresamos al punto donde realmente estabamos. EnTransferTest. Lo ejecutamos. Barra Verde.Probando el servicio detransferencia.
  57. 57. Refactoring.La forma de construir la TransferOperation no es del todo agradable. sustituimos lossetters actuales por un semi-builder mas intutitivo y comodo, definido con un DSL propio.Cambiamos el Test a como realmente queremos que luzca la llamada.Probando el servicio detransferencia.
  58. 58. Cambiamos el codigo de TransferOperation,Ejecutamos el Test, Barra Verde.
  59. 59. Transferencias entre 2 monedas distintas.Diseñamos nuestro Test. Primera aproximación.Sin factor de conversión. Barra VerdeProbando el servicio detransferencia.
  60. 60. Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximaciónProbando el servicio detransferencia.
  61. 61. Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximacion. Hacemoscompilar el codigo. Ejecutamos. Barra rojaProbando el servicio detransferencia.
  62. 62. Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximación.Implementamos.Probando el servicio detransferencia.
  63. 63. Transferencias entre 2 monedas distintas.Con factor de conversión. Primera aproximación. Ejecutamos los Tests. Barra RojaProbando el servicio detransferencia.
  64. 64. Transferencias entre 2 monedas distintas. Se arregla el bug quese acaba de introducir. Ejcutamos los Test. Barra Verde. (Ojotambien habría que verificar, con test que los valores estánmetidos en el mapa de conversionRates)Probando el servicio detransferencia.
  65. 65. Transferencias entre 2 monedas distintas. Refactorización SRP.Necesitamos otro servicio, Currency Service que se ocupe de laconversión. TransferService solo sabe de transferencias.Probando el servicio detransferencia.
  66. 66. Creamos la implementación extrayendo una clase nueva deTransferServiceImpl.
  67. 67.  Incluimos la dependencia en TransferService para que utilice la nuevadependencia.
  68. 68. Ejecutamos CurrencyTest. Barra Verde. Sin emabrgo luego deuna amplia refactorización como la hecha es necesario ejecutartoda la suite de tests para verificar que todo está correcto.
  69. 69. Transfer Test se ha roto con larefactorización, ya que se ha incluidouna nueva dependencia que nohabiamos considerado cuando hicimosel servicio. Debemos adaptar nuestroTest a esta nueva casuistica.
  70. 70.  En el caso anterior en realidad se debíahacer el test antes de añadir ladependencia a la claseimplementación. Siempre se debe atender primero alTest según los requerimientos y elcomportamiento que se quiere lograr
  71. 71. Mock Objects Introduciremos un Mock para ladependencia. ¿Qué es un Mock Object?
  72. 72. Mock Object. Mock hecho a mano
  73. 73. JMOCKNos permite con un lenguajeespecifico de dominio definirDobles de objetos paranuestros Test, y establecer lasexpectativas sobre estosobjetos.
  74. 74. Mock con Jmock. Y expectativas.Ejecutamos todos los tests. Barra verde
  75. 75. El uso de mocksEl uso de mocksSe puede establecer su necesidad encualquiera de los dos tiempos dediseño. Escribir el Test, o larefactorización.
  76. 76. Refactorizando CurrencyService. Esemapa de mapas es muy lioso. Se nosocurre mover la responsabilidad desaber el rate de cambio a la propiadivisa.
  77. 77.  Para hacer esto decidimos tambiénconversión establecer Rates a una divisaúnica y utilizar esta para los cambios.Usamos el Dólar.
  78. 78. Escribimos los Tests (En realidad se escribieron 1 a1 estos tests). Y Ejecutamos, Barra Roja.
  79. 79. Implementamos
  80. 80. Ejecutamos los tests. Green BarRefactorizamos CurrencyService
  81. 81. Persistiendo los cambiosPersistiendo los cambios. Servicio de persistencia de cuentas. Mock del Dao en Las transferencias. TDD.AccountService debe permitir persistir cuentas. No compila. Añadimos una nueva propiedad a la clase Account. El identificador.AccountNumber. Aqui incluimos el mock antes de implementar nada. Sabemos que por buena practica el Servicio no irá directocontra Repositorio.
  82. 82. Persistiendo los cambios - Diseñamos el Test con lasdependencias en Mente. - Nos damos cuenta de la necesidad deun identificador de cuenta. Y loincluimos en nuestro Test. - Siempre pensar en como queremosinvocar a nuestras APIs
  83. 83. Lo hacemos compilar. Implementamos en account service.Ejecutamos el test. Barra Verde.
  84. 84. Test Driving el DAO. Test deIntegración.Ahora haremos la implementacióndel DAO guiado por tests.Exactamente igual que como hastaahora. Solo que ahora interactuamoscon elemento externo. La Base deDatos, o sistema de ficheros. Peroempecemos por el test.
  85. 85. Utilizaremos el poderoso Spring Test Context para las pruebas deintegración. (Las siguientes pruebas se hicieron 1 a 1).
  86. 86. Implementamos (En realidad lo anteriorse hizo test a test. Pero para recortar loponemos todo de hecho con la primeraejecución nos dimos cuenta queAccount debía ser serializable ydebiamos implementar el equals y elhashcode para comparar Accounts) .
  87. 87. En algunos casos, los tests de integración son bastante maslentos que los tests unitarios como vemos.Ejecutamos la suite entera de tests
  88. 88. Persistiendo lastransferenciasEl servicio de transferencias ahora mismo nopersiste los datos. Debemos añadir esto a nuestraaplicación. Lo añadimos en el Test, lo hacemoscompilar, y lo implementamos en el servicio. Con elmismo procedimiento paso a paso hecho hasta ahora.Al final obtenemos el siguiente resultado. Obteniendola barra verde.
  89. 89. Ejecutamos. Barra Verde
  90. 90. TDD el controlador.Se basa en los mismos procedimientos queel probar las otras capas. Centrarnos en lafuncionalidad requerida, y simular los demascomponentes. Las dependencias. Sabemosque trabajaremos con Controllers de Spring.Lo primero que haremos será lafuncionalidad para presentar el formulario.
  91. 91. TDD El controlador.Lo hacemos compilar.Ejecutamos. Barra Roja
  92. 92. TDD el controladorImplementamos. Ejecutamos el Test. Barra Verde. En principiono hay refactorización que hacer.
  93. 93. TDD el controlador. El submit del formularioMocking HttpServletRequest.
  94. 94. TDD el controlador. Implementamos. Barra Verde.
  95. 95. Ejecutamos la Suite Entera deTests. Barra Verde.
  96. 96. El test funcional. Creamos las JSPs requeridas segun nuestros Test, nuestrocontroller y nuestro conocimiento de Spring MVC.Transfer.jsp
  97. 97. transferResult.jsp
  98. 98. Todo dentro del Test El Test funcional idealmente es capazde iniciar todo su entorno. En nuestrocaso iniciamos el Tomcat.
  99. 99. Utilizamos Cargo para controlar el servidor.
  100. 100. Preparando para el Test Funcional
  101. 101. Las 2 fases del BUILD
  102. 102. Ejecutando el Test Funcional. Incluimos Un setup Completo en el test que inicia elservidor tomcat.
  103. 103. Ejecutamos la Suite Entera Incluyendo Funcionales
  104. 104. Las 2 Fases del BUILD En un entorno de integración continua. Mvn test: Ejecuta los Tests unitarios, seejecutara en cada momento Mvn integration-test: Ejecuta los Testsfuncionales. 2 veces al dia.
  105. 105. Revisando el Code Coverage Cobertura. Mvn site Mas que medir la cobertura porporcentaje. Estar conscientes de quehemos probado lo necesario.
  106. 106. Reporte del EjemploPACKAGE CLASES LINE COVERAGEALL PACKAGES 16 75%ORG.PT.TDD 1 92%ORG.PT.TDD.DAO 2 75%ORG.PT.TDD.DOMAIN 3 69%ORG.PT.TDD.EXCEPTION3 50%ORG.PT.TDD.FORM 1 100%ORG.PT.TDD.SERVICE 6 90%Cobertura136/17915/2026/2864/926 1218/207/7
  107. 107. Cobertura
  108. 108. Cobertura
  109. 109. Conclusiones-- TDD nos ayudan a mantener el foco de loque queremos desarrollar.-- TDD nos sirve como red de seguridad paraatrapar Bugs lo antes posible.-- TDD nos da seguridad de que lo quedesarrollamos funciona.
  110. 110. Bibliografía
  111. 111. Preguntas
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×