Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Como escribir buenos tests al hacer TDD

2 227 vues

Publié le

Charla de Agiles 2016, Quito.
Es sobre TDD, cómo escribir los tests y un poco de diseño

Publié dans : Logiciels

Como escribir buenos tests al hacer TDD

  1. 1. agile software development & services Cómo escribir buenos test al hacer TDD www.10pines.com Hernán Wilkinson Twitter: @HernanWilkinson Blog: objectmodels.blogspot.com www.10pines.com
  2. 2. ¿Qué es TDD? Técnica de Aprendizaje Iterativa e Incremental Basada en Feedback Inmediato Como side-effect: Recuerda todo lo aprendido Y permite asegurarnos de no haber “desaprendido” Incluye análisis, diseño, programación y testing
  3. 3. ¿Cómo se hace TDD? 1) Escribir un test - Debe ser el más sencillo que se nos ocurra - Debe fallar al correrlo
  4. 4. ¿Cómo se hace TDD? 1) Escribir un test - Debe ser el más sencillo que se nos ocurra - Debe fallar al correrlo 2) Correr todos los tests - Implementar la solución más simple que haga pasar el/los test/s - GOTO 2 hasta que “todos los tests” pasen
  5. 5. ¿Cómo se hace TDD? 1) Escribir un test - Debe ser el más sencillo que se nos ocurra - Debe fallar al correrlo 2) Correr todos los tests - Implementar la solución más simple que haga pasar el/los test/s - GOTO 2 hasta que “todos los tests” pasen 3) Reflexiono - ¿Se puede mejorar el código? - Sí -> Refactorizar. GOTO 2 - No -> GOTO 1
  6. 6. ¿Cómo se hace TDD? 1) Escribir un test - Debe ser el más sencillo que se nos ocurra - Debe fallar al correrlo 2) Correr todos los tests - Implementar la solución más simple que haga pasar el/los test/s - GOTO 2 hasta que “todos los tests” pasen 3) Reflexiono - ¿Se puede mejorar el código? - Sí -> Refactorizar. GOTO 2 - No -> GOTO 1
  7. 7. ¿Cómo se hace TDD? 1) Escribir un test - Debe ser el más sencillo que se nos ocurra - Debe fallar al correrlo 2) Correr todos los tests - Implementar la solución más simple que haga pasar el/los test/s - GOTO 2 hasta que “todos los tests” pasen 3) Reflexiono - ¿Se puede mejorar el código? - Sí -> Refactorizar. GOTO 2 - No -> GOTO 1
  8. 8. Regla 1: Si el test no falla la primera vez que corre es porque: a) Estamos testeando algo testeado b) Nos adelantamos en el paso 2
  9. 9. ¿Cómo se hace TDD? 1) Escribir un test - Debe ser el más sencillo que se nos ocurra - Debe fallar al correrlo 2) Correr todos los tests - Implementar la solución más simple que haga pasar el/los test/s - GOTO 2 hasta que “todos los tests” pasen 3) Reflexiono - ¿Se puede mejorar el código? - Sí -> Refactorizar. GOTO 2 - No -> GOTO 1
  10. 10. ¿Cómo se hace TDD? 1) Escribir un test - Debe ser el más sencillo que se nos ocurra - Debe fallar al correrlo 2) Correr todos los tests - Implementar la solución más simple que haga pasar el/los test/s - GOTO 2 hasta que “todos los tests” pasen 3) Reflexiono - ¿Se puede mejorar el código? - Sí -> Refactorizar. GOTO 2 - No -> GOTO 1
  11. 11. Regla 2: Sensar el tiempo que nos lleva realizar cada paso
  12. 12. Tiempo Si nos lleva mucho tiempo escribir el test  El test no es el más sencillo ¿Nos cuesta mucho crear los objetos para la prueba?  Hay que crear objetos que ayuden en la creación de objetos  El diseño del sistema no es bueno y nos dificulta la escritura del test
  13. 13. Tiempo Si nos lleva mucho tiempo hacer pasar el test  El test no era el más sencillo  Borrar el test e intentar con uno más sencillo La implementación no resuelve el problema  ¡Debuggear! El diseño del sistema no es bueno y nos dificulta la implementación de nueva funcionalidad  Hacer paso 3 para mejorar el diseño antes de seguir
  14. 14. Tiempo Los test tardan mucho tiempo en ejecutar  El sistema está acoplado con recursos externos que hace que ejecute “lento”. Ejemplo: Base de datos Los test no verifican funcionalidad sino performance  Test de performance se hacen con testing, no TDD
  15. 15. Tiempo Tardo mucho en hacer refactorings  ¡Aprender refactorings automatizados! Si están programando con editores de texto ¡pasar a un IDE! Aprender como hacer cambios chicos por medio de refactorings encadenados El diseño del sistema es muy malo, esta muy acoplado y no queda otra que tomarse tiempo para arreglarlo 
  16. 16. Estructura de los tests Setup Exercise Assert Establece el contexto inicial para la ejecución del test. Pre-condición del test (puede ser reificado en mensaje setUp) Ejercita la funcionalidad específica que se está testeando. Determina QUÉ se está testeando. Verifica que los resultados sean los esperados. Post-condición del test
  17. 17. Ejemplo ▶ Algoritmo para calcular los factores primos de un número entero. Debe devolver una lista con ellos – 1 -> {} (no tiene factores primos) – 2 -> { 2 } – 3 -> { 3 } – 4 -> { 2,2 } – 5 -> { 5 } – 6 -> { 2,3 } – 7 -> { 7 } – 8 -> { 2,2,2 } – 9 -> { 3,3 } – 10 -> { 2,5 } – Etc
  18. 18. ¿Cómo lo llamamos?
  19. 19. ¿Qué tal así?
  20. 20. ¿Entonces cómo llamamos este?
  21. 21. Regla 3: Nombrar los tests sintetizando el setup, exercise y assertions en una frase Tip: Nombrar los tests cuando hayamos avanzado en la solución
  22. 22. ¿Cuál es el setup y exercise?
  23. 23. Setup
  24. 24. Exercise
  25. 25. Assert
  26. 26. ¿Qué tal este?
  27. 27. No suena muy bien…
  28. 28. ¿Cómo llamamos estos tests?
  29. 29.  Nombres casi iguales…  “Nombres repetidos”  ¡Tests del mismo caso!
  30. 30. ¡Mismo caso funcional!
  31. 31. Regla 4: Nombrar los tests en base al caso funcional y no en base a los datos de prueba
  32. 32. Tip: Dato de Prueba != Caso de Prueba  Dato de Prueba: Ejemplos concretos que “definen” un caso de prueba  Caso de Prueba: Generalización que incluye los datos de prueba
  33. 33. ¡Me da miedo! ¿Qué pasa si …?
  34. 34.  Decisión complicada…  Números primos infinitos…  Ver la implementación lamentablemente
  35. 35. Ejemplo ▶ Modelar un Calendario de días feriados al que se le pueda preguntar si una fecha es feriado o no ▶ Se pueda indicar qué días son feriados de la siguiente manera: – Por medio de un día de la semana, ej. Domingo – Por medio de un día de un mes, ej. 25 de Diciembre – Por medio de un día particular, ej. 20/4/2012
  36. 36. ¿Cómo lo llamamos?
  37. 37.  ¿Si hago un test con 3 días pasará?  ¿y con 4 …?  ¿y con 7?
  38. 38. ¡Inducción Incorrecta!
  39. 39. Regla 5: ¡Los tests no son una verificación formal! Técnica: Testar con datos testigos Técnica: Testar con datos bordes
  40. 40. ¿Aserción luego del set up?
  41. 41. ¿Aserción luego del set up? Para pensar… first ?
  42. 42.  Separar el test en 2
  43. 43. ¿Exercise luego de aserción?
  44. 44. ¿Exercise luego de aserción? Para pensar… first ? second?
  45. 45.  Separar el test en 2
  46. 46. Regla 6: Los tests deben seguir la estructura setup- exercise-assertion
  47. 47. first ? second?
  48. 48. Pensar en “tipo” no en implementación
  49. 49. Regla 7: Las aserciones sobre colecciones no deben acoplar a la implementación Regla 8: Las aserciones sobre colecciones deben asegurar la doble inclusión Tip: asertar size e inclusión de cada objeto
  50. 50. Aserción repetidaAserción repetida
  51. 51. ¡Reificar aserciones!
  52. 52. Regla 9: Los tests son un sistema más que hay que desarrollar y mantener. Hacerlo usando las mismas reglas de diseño que el sistema principal
  53. 53. Regla 10: Los tests son un sistema que usa el sistema principal, por lo tanto los tests nos convierten en los primeros usuarios del sistema principal y nos hacen sufrir sus problemas
  54. 54. ¿Va a funcionar siempre?
  55. 55. ¿Qué problema de diseño tiene esta implementación?
  56. 56. ¡Saco acoplamiento parametrizando la fecha!
  57. 57. ¡Ahora la fecha de prueba es relativa, no absoluta!
  58. 58. ¡Ahora va a funcionar siempre, no importa que día sea hoy!
  59. 59. Regla 11: Cuando hay dependencia entre datos de prueba e implementación, romper el acoplamiento parametrizando Tip: siempre usar datos de prueba relativos, no absolutos
  60. 60. Regla 12: Nunca acoplar la implementación con fuentes de información ni sistemas externos, parametrizar
  61. 61. Acceso via interface REST  El carrito pasa a ser inválido (inutilizable) luego de 30 minutos de no usarlo
  62. 62. ¿Qué principio de diseño se está violando? ¿Cómo lo evito? ¿Qué tiene que controlar el test?
  63. 63. Reloj manual para controlar el paso del tiempo
  64. 64. Parametrizo cómo obtiene la hora Reloj manual para controlar el paso del tiempo
  65. 65. Parametrizo cómo obtiene la hora Reloj manual para controlar el paso del tiempo Simulo paso del tiempo
  66. 66. Regla 13: El test tiene que estar en control de TODO (hasta del paso del tiempo si es necesario) Tip: Si hay que controlar el tiempo, simular el reloj
  67. 67. ¿Cómo hay que testear excepciones?
  68. 68. Solo la colaboración que levanta la excepción
  69. 69. Solo la colaboración que levanta la excepción Aserto que se levantó la ex. esperada
  70. 70. Solo la colaboración que levanta la excepción Aserto que se levantó la ex. esperada Aserto sobre la post-condición
  71. 71. Regla 14: Cuando se testea por excepciones se debe: 1) Una colaboración en el try 2) Asertar exc. correcta 3) Asertar post-condición Tip: falta de aserción sobre post-condición puede indicar que no estamos modelando algo
  72. 72. Referencia directa a la base de datos
  73. 73. Referencia directa a la base de datos y cómo se busca en ella ¿Cómo rompo este acoplamiento?
  74. 74. Modela un sub-sistema
  75. 75. Lo implementa de manera persistente
  76. 76. Lo implementa de manera transient
  77. 77. Regla 15: Modelar los conjuntos de objetos (sistemas) Tip: Queda representada la arquitectura del sistema por medio de objetos
  78. 78. ¿Cómo defino que subsistema usar?
  79. 79. Regla 16: Modelar los ambientes de ejecución y dejarlos como único punto de acceso a toda la información
  80. 80. ▶ Regla 1: Si el test no falla la primera vez es porque … ▶ Regla 2: Sensar el tiempo que nos lleva realizar cada paso ▶ Regla 3: Nombrar los tests sintetizando el setup, exercise y assertions en una frase ▶ Regla 4: Nombrar los tests en base al caso funcional y no en base a los datos de prueba Conclusiones
  81. 81. ▶ Regla 5: ¡Los tests no son una verificación formal! ▶ Regla 6: Los tests deben seguir la estructura setup-exercise-assertion ▶ Regla 7: Las aserciones sobre colecciones no deben acoplar a la implementación ▶ Regla 8: Las aserciones sobre colecciones deben asegurar la doble inclusión Conclusiones
  82. 82. ▶ Regla 9: Los tests son un sistema más que hay que desarrollar y mantener … ▶ Regla 10: … los tests nos convierten en los primeros usuarios del sistema … ▶ Regla 11: … romper el acoplamiento parametrizando ▶ Regla 12: Nunca acoplar la implementación con fuentes de información ni sistemas externos, parametrizar Conclusiones
  83. 83. ▶ Regla 13: El test tiene que estar en control de TODO ▶ Regla 14: Cuando se testea por excepciones se debe … ▶ Regla 15: Modelar los conjuntos de objetos (sistemas) ▶ Regla 16: Modelar los ambientes de ejecución y dejarlos como único punto de acceso a toda la información Conclusiones
  84. 84. agile software development & services Muchas gracias! info@10pines.com www.10Pines.com twitter: @10Pines Argentina Tel.: +54 (11) 6091-3125 Av. Alem 693, 5B (1001) Buenos Aires

×