Kata Tenis Completa Paso a Paso. Python Sevilla 30/11/2012

1,911 views

Published on

Kata tenis en Python paso a paso con

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

No Downloads
Views
Total views
1,911
On SlideShare
0
From Embeds
0
Number of Embeds
14
Actions
Shares
0
Downloads
26
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Kata Tenis Completa Paso a Paso. Python Sevilla 30/11/2012

  1. 1. Kata con Python Python-Sevilla
  2. 2. Objetivos • Estudiar paso a paso cómo resolver la kata Tenis con TDD y Python • Exponer errores y ver la manera de detectarlos. • Comparar distintas soluciones desarrolladas con TDD.Objetivos 2
  3. 3. Índice 1. Repaso de TDD 2. Kata Tennis. 3. PowerPoint-Driven Development. 4. Primer diseño (y pruebas). 5. Continuamos. 6. Refactorizar la clase Player. 7. El Partido de Tenis. 8. Random tennis 9. Conclusiones.Índice 10. Otras soluciones. 11. Extra 3
  4. 4. Repaso de TDD 4
  5. 5. 2. El proceso TDDEl proceso de TDD
  6. 6. 2. El Proceso TDDEscribimos un test que ponga de relieve funcionalidad que queremos implementarSi la prueba no falla estudiamos qué está sucediendo y elegimos otra. Escribimos el código mínimo (más corto) para que la prueba pase con éxito. No nos preocupamos de escribirlo bonito, tenemos libertad para tomar atajos
  7. 7. 2. El Proceso TDD Ejecutamos la prueba y cambiamos el código hasta que la prueba funciona. Quitamos los atajos y refactorizamos el código y las pruebas.Y cómo Triangulando, completando el conjunto decontinuamos? pruebas o eligiendo una nueva funcionalidad.
  8. 8. Kata: Tennis 8
  9. 9. Cata - Tenis Reglas • un jugador comienza con puntación 0. • Los puntos se ganan en esta secuencia: 0 -> 15 -> 30 - > 40. • Si un jugador consigue 40 y puntúa de nuevo, el jugador gana el juego si el otro no tiene 40 puntos. • Si los dos jugadores tienen al mismo tiempo 40 puntos, se llama "iguales" (deuce en inglés) • Puntuar durante iguales, da al jugador "ventaja". Si el otro jugador puntúa en ese momento, la puntuación vuelve a iguales. • Si un jugador tiene "ventaja" y puntúa de nuevo, el jugador gana el juego.http://www.solveet.com/exercises/Kata-Tennis/13 9
  10. 10. Cata - Tenis Metas: • Los jugadores deben poder ganar puntos. • El juego debe terminar con un ganador. • Debes de manejar la casuística de "iguales" • Después de terminar el juego, debe determinarse quién es el ganador. • Debe ser posible obtener la puntuación de cualquier de los jugadores en cualquier momento del partido. 10
  11. 11. PowerPoint-Driven Development 11
  12. 12. La primera prueba No intentes hacerlo todo de golpe. • Elige algo pequeño y simple. • Escribe una prueba que lo muestre. • Codifica la prueba. • Por ejemplo: pasar de 0 a 15 o el match aún no ha terminado 12
  13. 13. La Segunda Prueba ¿…y ahora? • ¿Cuál es la prueba que te hace avanzar más? • Por ejemplo puedes continuar con las puntuaciones hasta la casuística de los 40. • Recuerda refactorizar. 13
  14. 14. Ha pasado el tiempo ¿atascado? • No te preocupes si tienes que volver a empezar. • No es una pérdida de tiempo. Ya verás como la siguiente vez te sale MUCHO MEJOR. 14
  15. 15. Esto se acaba ¿Has terminado?• ¿Y si intentas simular una partida de tenis con números aleatorios?. ¿No has terminado?• Refactoriza y que quede bonito 15
  16. 16. Primer diseño (y pruebas) 16
  17. 17. Primeros pasosMetas:• Los jugadores deben poder ganar puntos. Tenemos que empezar por• El juego debe terminar con algo. ¿Por dónde? un ganador.• Debes de manejar la casuística de "iguales"• Después de terminar el juego, debe determinarse quién es el ganador. Mover• Debe ser posible obtener la puntuación de cualquier de los jugadores en cualquier momento del partido. 17
  18. 18. Primeros pasos Ejemplos prácticos (candidatos a casos de prueba)Acción Estado Resultado-- El jugador no ha anotado ningún tanto 0 puntosJugador anota un tanto Sin puntos 15 puntosJugador anota un tanto 15 puntos 30 puntosJugador anota un tanto 30 puntos 40 puntosJugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos GanaJugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos VentajaJugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntosJugador anota un tanto Ventaja Gana 8 casos de prueba posibles 18
  19. 19. Primeros pasos Manos a la obraAcción Estado Resultado-- El jugador no ha anotado ningún tanto 0 puntosJugador anota un tanto Sin puntos 15 puntosJugador anota un tanto 15 puntos 30 puntosJugador anota un tanto 30 puntos 40 puntosJugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos GanaJugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos VentajaJugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntosJugador anota un tanto Ventaja Gana 8 casos de prueba posibles 19
  20. 20. Primeros pasos ¿Cómo será nuestra prueba? 1 • ¿Cómo creamos un jugador? 2 • No hay nada que hacer 3 • ¿Cómo conocemos la puntuación de un jugador? • ¿Cómo se expresa la Con nuestra primera prueba vamos a puntuación del jugadorempezar a contestar a estas preguntas y, así,veremos si elegimos una buena alternativa o no
  21. 21. Primeros PasosTambién hemos tomado muchas decisiones de diseño. He decidido crear un módulo Tennis que contiene una clase Player He decidido utilizar un constructor sin parámetros He decidido añadir un método sin parámetros para saber la puntuación de ese jugador He decidido que la puntuación sea una cadena de texto
  22. 22. Primeros PasosCentramos nuestro foco en escribir el mínimo códigopara pasar esta prueba…
  23. 23. Primeros Pasos Para cambiar esto necesitaré más adelante una prueba que me haga cambiarlo. A por ello.Nada que refactorizar: ni código ni pruebas.
  24. 24. Primeros pasos Ejemplos prácticos (candidatos a casos de prueba)Acción Estado Resultado-- El jugador no ha anotado ningún tanto 0 puntosJugador anota un tanto Sin puntos 15 puntosJugador anota un tanto 15 puntos 30 puntosJugador anota un tanto 30 puntos 40 puntosJugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos GanaJugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos VentajaJugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntosJugador anota un tanto Ventaja Gana 24
  25. 25. Primeros Pasos DespuésAntes Triangulación.Podríamos refactorizar algunos detalles.
  26. 26. Primeros Pasos Ya tenemos nuestras primeras pruebas listas y nuestro código crece…. Pero, ¿qué estamos haciendo?• Estamos diseñando cómo implementamos la puntuación de un jugador.• Estamos diseñando cómos otras partes del código indicarán que un jugador ha puntuado.• Estamos entrando en foco más en diseñar el código qué nos es útil que en implementar el problema.
  27. 27. Continuamos 27
  28. 28. Pruebas de anotación Ejemplos prácticos (candidatos a casos de prueba)Acción Estado Resultado-- El jugador no ha anotado ningún tanto 0 puntosJugador anota un tanto Sin puntos 15 puntosJugador anota un tanto 15 puntos 30 puntosJugador anota un tanto 30 puntos 40 puntosJugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos GanaJugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos VentajaJugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntosJugador anota un tanto Ventaja Gana 28
  29. 29. Pruebas de anotación
  30. 30. Pruebas de anotación Mal olor: demasiado código repetido, diseño difícil de probar.Esta refactorización nos pone de relieve otro problema…que ignoramos
  31. 31. Pruebas de anotación Ejemplos prácticos (candidatos a casos de prueba) Acción Estado Resultado -- El jugador no ha anotado ningún tanto 0 puntos Jugador anota un tanto Sin puntos 15 puntos Jugador anota un tanto 15 puntos 30 puntos Jugador anota un tanto 30 puntos 40 puntos Jugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos Gana Jugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos Ventaja Jugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntos Jugador anota un tanto Ventaja GanaParece que vamos avanzando. 31
  32. 32. El segundo jugador 32
  33. 33. Anotando con el segundo jugador Necesitamos al segundo jugador.Acción Estado Resultado-- El jugador no ha anotado ningún tanto 0 puntosJugador anota un tanto Sin puntos 15 puntosJugador anota un tanto 15 puntos 30 puntosJugador anota un tanto 30 puntos 40 puntosJugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos GanaJugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos VentajaJugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntosJugador anota un tanto Ventaja Gana 33
  34. 34. Anotando con el segundo jugadorLas pruebas anteriores ya no se ejecutan porque no les pasaba un jugador (ni los necesitaban). Hay que arreglarlo ?
  35. 35. Anotando con el segundo jugadorNo ha sido una buena prueba, no he introducido nada quenecesitara ni que haya hecho crecer mi código.
  36. 36. Anotando con el segundo jugador Necesitamos al segundo jugador. Acción Estado Resultado -- El jugador no ha anotado ningún tanto 0 puntos Jugador anota un tanto Sin puntos 15 puntos Mover derecha 15 puntos 30 puntos Mover derecha 30 puntos 40 puntos Mover derecha 40 puntos y el otro jugador no tiene 40 puntos Gana Mover derecha 40 puntos y el otro jugador tiene 40 puntos Ventaja Mover derecha 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntos Mover derecha Ventaja GanaHace evolucionar mi sistema. 36
  37. 37. Anotando con el segundo jugadorLas pruebas anteriores ya no se ejecutan porque a veces el segundo jugador es “None”. Hay que arreglarlo.
  38. 38. Anotando con el segundo jugadorUn apaño (añadir a un segundo jugador como parámetro y hacerloNone para que mis pruebas anteriores ejecuten) olor me lleva aotro mal olor (ver si tengo un segundo jugador o no).Mejor simplificar y que todas las pruebas trabajen con un segundojugador refactorizar.
  39. 39. Anotando con el segundo jugador Necesitamos al segundo jugador. Acción Estado Resultado -- El jugador no ha anotado ningún tanto 0 puntos Jugador anota un tanto Sin puntos 15 puntos Jugador anota un tanto 15 puntos 30 puntos Jugador anota un tanto 30 puntos 40 puntos Jugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos Gana Jugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos Ventaja Jugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntos Jugador anota un tanto Ventaja GanaEsta es la última prueba clave. 39
  40. 40. Anotando con el segundo jugador
  41. 41. Anotando con el segundo jugador La última prueba. Acción Estado Resultado -- El jugador no ha anotado ningún tanto 0 puntos Jugador anota un tanto Sin puntos 15 puntos Jugador anota un tanto 15 puntos 30 puntos Jugador anota un tanto 30 puntos 40 puntos Jugador anota un tanto 40 puntos y el otro jugador no tiene 40 puntos Gana Jugador anota un tanto 40 puntos y el otro jugador tiene 40 puntos Ventaja Jugador anota un tanto 40 puntos y el otro jugador tiene ventaja Se queda como está y el otro jugador vuelve a 40 puntos Jugador anota un tanto Ventaja GanaEsta prueba no sería necesaria. Como vamos a ver 41
  42. 42. Anotando con el segundo jugadorFunciona !!!
  43. 43. Conclusiones Hemos terminado pero…..• Las pruebas son difíciles de entender.• He escrito código sólo para las pruebas.• He decidido cómo representar las puntuaciones (cadenas). Arreglémoslo.
  44. 44. Refactorizar la clase Player 44
  45. 45. Refactorizando Player Usamos constantes
  46. 46. Refactorizando PlayerUn mal olor que quitamos.
  47. 47. Refactorizando Player No nos olvidemos de refactorizar las pruebas
  48. 48. Refactorizando Player Adiós a los malos olores.• Ahora as pruebas hablan la lógica del negocio y utilizan sus conceptos, en vez de trabajar con valores numéricos y cadenas.• Lo que más puede cambiar está solo en un sitio.• Tapo el apaño del constructor (a la espera de mocks).
  49. 49. El Partido de Tennis 49
  50. 50. El Partido de TennisMetas:• Los jugadores deben poder Método winPoint ganar puntos.• El juego debe terminar con un ganador.• Debes de manejar la Método winPoint casuística de "iguales"• Después de terminar el juego, debe determinarse quién es el ganador.• Debe ser posible obtener la puntuación de cualquier de Método getScore los jugadores en cualquier momento del partido. 50
  51. 51. El Partido de Tennis Ejemplos prácticos (candidatos a casos de prueba)Acción Estado ResultadoJugador anota un tanto Dos jugadores, ningún ganador El juego continúaJugador anota un tanto Dos jugadores, un único ganador El juego termina. Se indica el ganador2 casos de prueba posibles (de entrada).Estos ejemplos de prueba no son completos. No hay que preocuparse, ya descubriremos qué falla más adelante 51
  52. 52. El Partido de Tenis • Crear la clase match • Darle un método playMatch • Hacer que el método anote al jugador A
  53. 53. El Partido de TenisPodemos refactorizar el caso de prueba. Aprovechar lo que ya tenemos del otro conjunto de pruebas No exponer detalles de la interfaz. Actuar, no pedir información
  54. 54. El Partido de TenisHemos refactorizado el código en desarrollo y las pruebas.
  55. 55. El Partido de Tenis Ejemplos prácticos (candidatos a casos de prueba)Acción Estado ResultadoJugador anota un tanto Dos jugadores, ningún ganador El juego continúaJugador anota un tanto Dos jugadores, un único ganador El juego termina. Se indica el ganador ¿Estamos a una prueba de acabar el desarrollo? Comprobémoslo 55
  56. 56. El Partido de TennisNo hacemos nada.
  57. 57. El Partido de Tenis Ejemplos prácticos (candidatos a casos de prueba)Acción Estado ResultadoJugador anota un tanto Dos jugadores, ningún ganador El juego continúaJugador anota un tanto Dos jugadores, un único ganador El juego termina. Se indica el ganador Aquí falta algo ¿Qué ha pasado? 57
  58. 58. El Partido de Tenis• Hay un valor de prueba que no estamos tratando.• ¿Cómo podemos hace que anote el otro jugador?• ¿Cómo podemos tener una prueba que siempre puntúe B y sea ganador¿ ¿y otra en la que puntué primero A y después B?• En verdad lo que queremos decir es….• ¿Cómo podemos cambiar lo que pasa dentro del while en el método playmatch sin montar un follón?• ¿Hemos hecho un mal diseño y tenemos que retroceder?• Veámoslo.
  59. 59. El partido de Tennis ¿Cómo podeos hacer que, en algunas pruebas puntúe el jugador A y en otras puntúe el jugador B?Evitamos la sobre ingeniería y buscamos la solución más sencilla que se nos ocurra
  60. 60. El Partido de TennisVamos a reescribir las prueba para poder introducir los valores de prueba (en este caso el jugador que anota. Nada de momento.
  61. 61. El Partido de TenisQue gane el jugador B. Bucle infinito Ok
  62. 62. El Partido de Tenis Hemos terminado pero…..• Hemos hecho un apaño que nos convence poco.• ¿Estamos seguros de que funciona?• ¿Podríamos modificarlo fácilmente?• ¿Es fácil de entender? Arreglémoslo.
  63. 63. El Partido de TenisTodo sigo funcionando.
  64. 64. El Partido de TenisMetas:• Los jugadores deben poder Método winPoint ganar puntos.• El juego debe terminar con Método winPoint un ganador.• Debes de manejar la Método winPoint casuística de "iguales"• Después de terminar el juego, debe determinarse Método winPoint quién es el ganador.• Debe ser posible obtener la puntuación de cualquier de Método getScore los jugadores en cualquier momento del partido. 64
  65. 65. Random Tenis 65
  66. 66. Random Tenis• ¿Y si se calcula aleatoriamente el jugador que anota?• ¿Y si ejecuto muchos partidos seguidos y compruebo que todo funciona correctamente?• Esto ya no son pruebas unitarias.• Si podemos hacerlo sin cambiar una coma de nuestro código es una buena indicación.• Si tenemos que cambiar algo, lo estamos mejorando. Vamos a hacerlo
  67. 67. Random TenisRandomPlay aún no está hecho
  68. 68. Random Tenis Esto no es código de producción ,sino de pruebas Todo funciona a la primera¿Por qué limitarnos a un único partido? ¿Por qué nojugamos 10.000? Vamos a hacerlo
  69. 69. Random Tenis 10.000 partidos……Este test no debería de fallar si todo lo hicimos bien (y el test está bien escrito)
  70. 70. Random Tenis Ooops, demasiado lento. No vale para prueba unitaria.Pues parece que funciona.
  71. 71. Conclusiones denuestra solución 71
  72. 72. Conclusiones• Después de 10.000 partidas no hemos detectado ningún error.• ¿Podemos decir que el software funciona?• Nunca.• Solo estamos buscando unos errores concretos, puede tener otros que no estemos buscando.• Los 10.000 partidas se basan en algo que no está probado.• Si RandomScore tiene fallos, las pruebas pueden dar falsos positivos
  73. 73. Conclusiones• Notas: – No está contemplado que se siga puntuando después de que un jugador gane (no lo pone en los requisitos pero podemos hacerlo si lo consideramos adecuado).
  74. 74. Otras soluciones 74
  75. 75. Otras soluciones TDD in Python in 5 minutesSetScore TestSetWinning: 6 pruebas TestScoreNames: 1 prueba http://css.dzone.com/articles/tdd-python-5-minutes
  76. 76. Otras solucionesTDD in Python in 5 minutes
  77. 77. Otras soluciones Solveet. Kata TDDSin pruebasPlayerMétodo game https://github.com/andrewnix/Kata-Tennis-Python/
  78. 78. Otras solucionesMétodo game
  79. 79. Otras Soluciones Solveet. Kata TDD Sin pruebas Decorador Métodohttps://github.com/andrewnix/Kata-Tennis-Python/
  80. 80. Otras Soluciones Solveet. Kata TDD Sin pruebas Decorador Métodohttps://github.com/andrewnix/Kata-Tennis-Python/
  81. 81. Otras Soluciones Solveet. Kata TDDPruebas a ojoGamePlayer
  82. 82. Otras SolucionesPruebas a ojoGamePlayer
  83. 83. Otras SolucionesSolveet. Kata TDD
  84. 84. Actividades • Consulta las soluciones si pruebas • ¿Crees que habrían salido estas soluciones haciendo TDD? • ¿Serías capa de escribir pruebas para ese código tal cuál está escrito, sin modificarlo?Autoevalua TDD 84
  85. 85. Extras 85
  86. 86. Extras• Repositorio GitHub: https://github.com/javierj/kata-dojous http://www.slideshare.net/Javier_J 86
  87. 87. Extra Ejemplo de mocks en Pythonhttp://iwt2-javierj.tumblr.com/post/36695988608/mocks-en-python-previa-python-tddEjemplo de Behave en Pythonhttp://iwt2-javierj.tumblr.com/post/36762766836/atdd-bdd-con-python-y-behave-previa-python-tdd 87
  88. 88. Python-Sevilla Python_Sevilla / #PySVQhttp://www.linkedin.com/groups/PythonSevilla-4685758 https://groups.google.com/forum/?fromgroups=#!forum/python-sevilla.

×