TDD - Sesión 1

Events happening in the community are now at Drupal community events on www.drupal.org.
carlescliment's picture
Start: 
2012-11-06 20:00 - 22:00 UTC
Organizers: 
Event type: 
Training (free or commercial)

En la pasada DrupalCamp 2012 formamos un pequeño grupo de interesados en el TDD (desarrollo guiado por pruebas) y decidimos llevar a cabo una iniciativa para practicar esta metodología de programación.

En la reunión celebrada el 31 de noviembre finalmente decidimos cómo la llevaríamos a cabo. Este es el plan:

  • Celebraremos reuniones los martes y los jueves de 20 a 22 horas.
  • Resolveremos katas de programación; en principio tomaremos como fuente la web de 12meses12katas.
  • Serán reuniones online, buscaremos herramientas como google hangout.
  • Las primeras sesiones serán guiadas. Compartiré mi escritorio e iré explicando cómo implemento la kata. Serán sesiones interactivas donde podréis plantear preguntas y proponer otras soluciones.
  • Después de dos sesiones de iniciación, pasaremos a trabajar por separado. Lo ideal es resolver las katas en pair-programming, aunque también podemos hacerlas en "solo mode". Cuando las terminemos las iremos colgando en algún sitio y quedaremos para comparar y debatir nuestras soluciones.

Los que tengáis experiencia previa con TDD, podéis desarrollar directamente la kata por vuestra cuenta (o compartir también vuestros escritorios!).

Cualquiera puede participar, aunque quizá tendremos problemas técnicos si somos demasiados. Objetivo: aprender y divertirse.

Por favor, dejad vuestro e-mail aquí o enviádmelo a la cuenta carlescliment de gmail para que os pueda enviar la invitación de google hangouts.

¡Un saludo!

Comments

De categoria !

lgrtm's picture

Muchas gracias a todos, espero que nos lo pasemos bien como dice Carlos y podamos/pueda aprender un montón.

Nos vemos el martes compis.

emails

carlescliment's picture

Buenas.

Para poderos agregar al Google Hangouts voy a necesitar vuestros emails. Mi cuenta de gmail es "carlescliment" y podéis enviármelo también desde la pestaña contacto de mi perfil en esta web.

Os agregaré minutos antes de empezar.

¡Un saludo!

Gracias por la invitación

nramirezsalas's picture

Soy nuevo en TDD pero me interesa mucho y espero aprender... sobre el horario no podré ingresar a las 20 horas, puedo ingresar a las 21 horas espero no haya ningún problema es que a esa hora recién llego a casa.

Este es mi correo, nramirez@businesstech.pe (Google Apps)

Saludos.

--
Néstor Ramírez Salas
Drupal Web Developer
@nramirezsalas

Streaming

langelhc's picture

Hola,

Una sugerencia, no se si se podria hacer un sreamming?
es decir que nosotros podriamos seguirte desde youtube.

Saludos

Disculpas nramirez, no vi tu

carlescliment's picture

Disculpas nramirez, no vi tu respuesta a tiempo.

langelhc, intenté hacer un streaming por youtube pero solicité el servicio y no me llegó la autorización necesaria. Se supone que te envían un SMS al móvil, pero aún estoy esperando. ¡Tal vez en la próxima ocasión!

A los que asististeis a la reunión, muchas gracias y espero que os haya gustado. Como tuvimos tiempo (justo) de resolver la kata entera, creo que ya estáis preparados para intentar hacerla por vuestra cuenta.

Podemos de todos modos quedar mañana Jueves a la misma hora para empezar una nueva kata y conversar sobre las dudas que nos vayan saliendo.

¿Os interesa?

Aquí está la kata de noviembre de 12meses12katas: http://www.solveet.com/exercises/SQL-String-Generator/139

De categoria, lo único que

lgrtm's picture

De categoria, lo único que entiendo, en mi lugar que no tengo los conocimiento de php suficientes. Ir al ritmo de ayer se me hace difícil asimilar tanta información en cuanto a programación, pero si fuí capaz de entender todo perfectamente.

La kata de ayer fue espectacular de la manera que se expuso pero reconozco que necesito horas para practicarla, así que la kata de ayer la iré desgranando a lo largo de estos días e iré posteando akí las dudas, así me podréis corregir fallos o recomendarme otras soluciones seguro que mejores... :)

Por mi Carles me apunto a las propuestas que vayas subiendo. Yo soy un fijo akí :).

Además esto es un vicio ...!
Y gracias a ti.

Un saludo a todos.
Miguel

PD1 - al final se grabo la sesión de ayer?
PD2 - el libro de Carlosble muy chulo. Habla de todos los conceptos que vimos ayer (Sut, Arrange, etc...)

Muy interesante la clase

delineas's picture

Muy interesante la clase práctica de ayer. Muchos conceptos nuevos en los que hay que profundizar, eso también está claro.
Puede ser interesante de cara a la próxima reunión (sea el jueves o el martes) que tengamos en cuenta dos cosas
1) Trabajo propio. Esto es, enfrentarse a la kata para que vayan surgiendo las necesarias dudas. Tanto de TDD como de POO
2) Trabajo en equipo. No se como lo veréis, pero ya que en la sesión podemos participar todos, puede tener un formato más abierto. Aunque no completemos la nueva kata, ir aportando el como lo haríamos para iniciarla en conjunto.

Claro, para el punto 2 hay que darle caña al 1, de eso no hay duda :)

Personalmente yo daría unos

jsbalsera's picture

Personalmente yo daría unos días más, para que tuviéramos tiempo de practicar un poco lo visto ayer, o dejaría sitio a gente que no pudiera haber asistido.

Así, con un poco de trabajo individual, podríamos llevar los conceptos más asentados para seguir avanzando :-)

De nuevo gracias por todo, Carles!

Buenas, En primer lugar,

penyaskito's picture

Buenas,

En primer lugar, perdón por mi ausencia ayer.

Según Dave Thomas, el "padre" de las code katas:

"There needs to be no pressure: this is why it is hard to practice in a project environment. it helps to keep it fun: make small steps forward when you can."

No olvidéis que da igual no terminar la kata. De hecho, una técnica habitual de hacerlas es fijar un tiempo, desarrollarla en ese tiempo, borrar lo hecho y volver a empezar. La gracia está en practicar, discutir, sin presiones.

Personalmente mi interés en este grupo de trabajo es "obligarme" a hacer las katas (y empecé mal :-P). Por ello creo que no es un gran inconveniente que no haya tiempo para prácticar solo, sino que veo más importante el mantener el ritmo y la frecuencia de las katas que el dar tiempo a que cada uno la trabaje.

Así que quizá queráis replantearos si lo dejáis para el martes...

--
Christian López Espínola (@penyaskito)

Buenas aportaciones,

carlescliment's picture

Buenas aportaciones, Christian!

Además de obligarnos a hacer las katas, añadiría lo interesante de poder comentarlas en grupo y debatir soluciones.

¡Compartiendo siempre se aprende!

Estaría bien seguir la

carlescliment's picture

Estaría bien seguir la propuesta de delineas y hacer la kata más participativa. Todos podemos hablar y compartir el escritorio, de manera que podemos debatir tanto como queramos. Personalmente prefiero esta forma de organizarnos.

Si en cambio queréis otra sesión guiada yo también voy a necesitar más tiempo para poderla preparar y que avancemos más rápido (¡una kata normalmente no se resuelve en menos de dos horas!). Si queréis lo dejamos para el martes que viene.

Tengo ya varios emails y tweets de gente que no pudo acudir pero le gustaría ver la sesión. Jesús, creo que la estábais grabando, ¿no? ¿La podemos subir a algún sitio?

Gracias a vosotros y un saludo.

Buenas, carles. Nosotros al

jsbalsera's picture

Buenas, carles.

Nosotros al menos no la estábamos grabando, me parece que esta primera sesión se ha perdido en el limbo :(

Una vez visto el desarrollo

lgrtm's picture

Una vez visto el desarrollo de ayer, con una sesión sobra. Entre postear akí y compartir luego el escritorio con todos hay currete. Así que por mí nos vemos el martes que viene o al siguiente, no hace falta ir a piñon...

Que os parece ir posteando cada uno aki y que cada cual proponga un día para poder compartir escritorio y que se vaya apuntando la gente...

Otro que al final faltó

slv_'s picture

Buenas, y perdón por mi ausencia ayer. En principio no tenía "nada", pero acabó siendo uno de esos días en los que te aparece trabajo de la nada y acabas liado.

Personalmente yo también la preferiría también el martes que viene, más que nada porque mañana seguramente no pueda asistir pero la semana que viene estaré libre de nuevo.

Respecto a la grabación, si no se puede el streaming directo a través de Hangout, siempre se puede probar algo como XSplit y montar una cuenta en JustinTV para hacer streaming desde ahí. Yo lo he hecho alguna vez para TwitchTV (esto es parte de Justin), y no es muy difícil. Además también se queda la sesión guardada en la cuenta de Justin al terminarla directamente, sin tener que subir nada, así los que no hayan podido asistir siempre pueden verla luego.

Saludos!

Primera toma de contacto.

lgrtm's picture

Hola de nuevo, antes de empezar el test quería postear un esquema
que no está depurado pero por lo menos puedo empezar a construir la kata.

http://twitpic.com/bb7i3k

Pensáis que así en una buena forma de comenzar y posteriormente ampliar y optimizar el esquema-kata? o es pura basura :-P

Saludos y gracias por los reportes...
Miguel

El esquema está muy chulo

carlescliment's picture

El esquema está muy chulo como planteamiento inicial del problema, para tener las cosas claras.

En TDD el diseño no se planifica, pues va emergiendo poco a poco a través de los refactorings en cada test.

¡Un saludo!

¡Nos vemos el martes y 13

carlescliment's picture

¡Nos vemos el martes y 13 entonces!

Sobre colgar código, creo que es mejor hacerlo en github, mucho más fácil de consultar. ¿Os parece?

Gracias, yo ya he colgado un

lgrtm's picture

Gracias, yo ya he colgado un comienzo pero lo he dejado comentado para tenerlo de referencia. Conforme me salgan dudas que ya se asoman por las neuronas las posteo..

Hasta pronto.
Saludos.

Mi cuenta de github "lgrtm".

1º Question

lgrtm's picture

He visto que hay metodos que se usan sin pasar test como por ejemplo el sumar un punto a un player, pensaba que tenía que estar todo con test. Pero al revisar tu código por encima he visto que llamas a funciones que no tienen test, supongo que son necesarias para hacer funcionar los otros test, me equivoco?

Thk

Los métodos para añadir

carlescliment's picture

Los métodos para añadir puntos a un player [scoreLeft() y scoreRight()] están siendo ejercitados en el test junto al método getWinner(). De manera que para que getWinner() devuelva el resultado correctamente, es condición necesaria que scoreLeft() y scoreRight() funcionen bien.

Si recuerdas la kata, empezamos testeando unitariamente scoreLeft() y asegurándonos de que se había incrementado la puntuación con un método accesor getLeftScore(). Pero luego reflexionamos sobre ello y dijimos que había que evitar exponer la implementación de la clase con accesores para mantener el encapsulamiento. Es por esto que probábamos scoreLeft() y scoreRight() junto con getWinner() y eliminábamos los accesores innecesarios.

El objetivo es conseguir una interfaz pública lo más opaca posible, que oculte los detalles de la implementación de la clase.

Los métodos privados no se

carlescliment's picture

Los métodos privados no se pueden probar desde el test, puesto que al ser privados solo pueden ser invocados desde dentro de la propia clase.

Los métodos privados por lo general surgen de los refactorings y sirven para ayudar a hacer más legible el código, ya que damos un nombre lo más expresivo posible a secciones de código. De esta manera los métodos quedan mucho más cortos y las explicaciones adicionales con comentarios resultan innecesarias.

2º Question

lgrtm's picture

Revisando el test he visto una llamada de un objeto (no se si se dice así) tal cual que ahora no la entiendo o no la recuerdo de tu explicación.

$this->game->render($this->render);

Ahora no lo pillo :(

Thk

Hagamos un repaso...Una vez

carlescliment's picture

Hagamos un repaso...

Una vez teníamos la kata de la lógica del juego resuelta, pasamos al renderizado de los puntos.

En un principio empezamos metiendo un método render() en la clase Game que devolvía un string dependiendo de la puntuación. "15-0", "15-15", etc...

Posteriormente hablamos del Single Responsibility Principle, o Principio de una Sola Responsabilidad, y decidimos que toda la lógica del renderizado la íbamos a mover a una clase aparte.

Empezamos a desarrollar una clase Render con un método que recibía un Game:

public function render(Game $game) {
  // (...)
}

Pero descubrimos que si lo hacíamos así, la clase Render iba a necesitar acceder a las puntuaciones de los jugadores (representadas con números enteros). Esto nos obligaba a implementar métodos accesores que expusieran los atributos privados $leftScore y $rightScore de la clase Game, algo que como vimos antes no nos parecía bien (encapsulamiento).

Para evitar esto aplicamos la técnica que recibe el nombre de Inversión de Control. Es decir, la clase Render ya no iba a preguntar a Game por las puntuaciones. Iba a ser Game quien se las iba a decir al Render, manteniendo la encapsulación. Explicado de otra manera, "no nos llames, nosotros te llamaremos".

Por eso hicimos que la clase Game tuviese un método render() que aceptaba como parámetro un objeto Render.

public function render(Render $render) {
  $render->render($this->leftScore, $this->rightScore);
}

Así, el objeto render obtenía la información necesaria (las puntuaciones) sin necesidad de exponer los atributos de Game.

Adicionalmente a esta explicación, he estado repasando mi código y hay algo que no veo bien.

Si te fijas en el test del render, estamos probándolo a través de la clase Game.

// Arrange
$render = new Render;
$game = new Game;
$game->scoreLeft();
$game->scoreRight();
$game->scoreRight();

// Act
$output = $game->render($render);

// Assert
$this->assertEquals("15-30", $output);

Bien pues creo que esa manera de probar no es la correcta, porque no es un test unitario. No estamos ejercitando directamente el SUT, y por lo tanto no es un test unitario. En el caso de que la clase Game tuviese un defecto, seguramente fallaría también el test del render, aunque el render estuviese bien.

Si volviera a hacer la kata la haría así:

// Arrange
$render = new Render;

// Act
$output = $render->render(1, 2);

// Assert
$this->assertEquals("15-30", $output);

Nota: he actualizado el código en github: https://github.com/carlescliment/Katas/blob/master/tenis/tests/GameScore...

¡Un saludo!

Documentación.

lgrtm's picture

No encuentro documentación sobre la sintaxis de esto

                    -------------------

public function render(Render $render) {
$render->render($this->leftScore, $this->rightScore);
}

render(Render $render) -> Render (esto es lo que no entiendo y no encuentro la documentación).

He mirado en google y en php pero no encuentro nada.

el Render que aparece justo

carlescliment's picture

el Render que aparece justo tras el paréntesis se llama type hinting y es una feature bastante nueva en PHP.

Sirve para indicar que la función render debe recibir un objeto de la clase o interfaz Render. Si recibiese un objeto distinto, o un entero o un string, lanzaría una excepción.

Documentación.

lgrtm's picture

No encuentro documentación sobre la sintaxis de esto

                    -------------------

public function render(Render $render) {
$render->render($this->leftScore, $this->rightScore);
}

render(Render $render) -> Render (esto es lo que no entiendo y no encuentro la documentación).

He mirado en google y en php pero no encuentro nada.

Ok, entonces game es que le

lgrtm's picture

Ok, entonces game es que le pasa los datos a render a traves del metodo render sin que render tenga que hacer un petición ( se entiende que ya los tiene no? ).

Que interesante.

Gracias por tu tiempo.
Saludos.

¡exacto! Interesante y

carlescliment's picture

¡exacto!

Interesante y apasionante, ¿verdad? ^ ^

Ale las birras pagadas.

lgrtm's picture

Ale las birras pagadas. Juasss XD
Thk

Me va a costar un tiempo

lgrtm's picture

Me va a costar un tiempo hacer la kata, pero seguro que voy a aprender un huevo o más !!! XD

En unos días os cuento ...

3º Question

lgrtm's picture

Yo voy poniendo preguntas y cuando se pueda se contesta. No me gusta agobiar a la peña.

A que se refiere la palabra triangulación?
Thk

Como vimos, siempre

carlescliment's picture

Como vimos, siempre escribimos el código mínimo para que pase el test. Si hacemos una primera prueba sobre un método y esperamos que nos devuelva false, simplemente implementamos el return false.

  public function testItShouldReturnFalseWhenFoo() {
    // Arrange
    $object = new MyClass();

    // Act
    $result = $object->fooMethod();

    // Assert
    $this->assertFalse($result);

  public function fooMethod() {
    return false;
  }

Triangular significa ir añadiendo tests de manera que, para que pasen, nos veamos obligados a completar todo el código necesario (y a refactorizar).

La ventaja de triangular es que garantizamos escribir el mínimo código posible con la máxima refactorización.

Como comentó alguien durante la sesión, triangular bien es quizá una de las partes más difíciles de TDD.

Diferencia entre IC y DI ?

lgrtm's picture

Buenas, alguno podría explicarme cual es la diferencia entre Inversion de control e inyección de dependencias ?

Thk !

La inversión de control

carlescliment's picture

La inversión de control supone dar la vuelta al flujo tradicional del código, en el que unas clases (o procedimientos) preguntaban a otras por los datos necesarios. Con la IoC las clases ya no se preguntan cosas entre sí, sino que se "mandan" unas a otras (tell, don't ask).

Una manera de conseguir la inversión de control es mediante la inyección de dependencias, que se basa en que no se instancian objetos dentro de métodos de una clase, sino que se "inyectan" como parámetros en la función.

// No inyectado
public function sendMail() {
  $mailService = new MailService;
  $mailService->send($this->title, $this->body);
}

// Inyectado
public function sendMail(MailService $mailService) {
  $mailService->send($this->title, $this->body);
}

Como hay que asegurarse de que el objeto inyectado dispone de los métodos esperados, definimos una interfaz, que es un "contrato" de los métodos que debe implementar cualquier clase que la implemente.

Es decir, para conseguir la inversión de control estamos haciendo varias cosas:

1) Definir una interfaz, un protocolo de comunicación para todos los renders. La hemos llamado "Render", y establece que cualquier clase que la implemente debe implementar los métodos render($scoreLeft, $scoreRight), leftWins() y rightWins().

2) Una vez definida la interfaz, podemos inyectar cualquier render a nuestra clase Game. En la kata desarrollamos uno que convertía las puntuaciones a strings, pero podríamos escribir cualquier otro render, implementar la interfaz, y personalizar las respuestas de cada método.

3) La interfaz Render proporciona un método render($scoreLeft, $scoreRight) que permite invertir el control, ya que ya no es el render el que pregunta por los scores, sino el Game quien los da.

Leído y repasando links ...

lgrtm's picture

Leído y repasando links ...

"ping" en render ?

lgrtm's picture

Bueno el título se las trae, a falta de repasar el codigo de la kata, "Render" tiene que testear que le ha enviado unos datos "Game" ?

No, en el test unitario solo

carlescliment's picture

No, en el test unitario solo testeamos que Render devuelve correctamente el valor Y ante unos parámetros X. Es decir, testeamos Render de manera aislada.

Necesitaríamos un pequeño test adicional que probase que la colaboración entre la clase Render y la clase Game funciona. Eso sería un test de integración.

Edito: ese test de integración lo podríamos cambiar por un test con un mock. Pasamos a Game un mock de Render, y nos aseguramos de que se llaman a los métodos correctamente.

Mañana lo ponemos en práctica en un momento ;)

No sé si me estoy adelantando

jsbalsera's picture

No sé si me estoy adelantando y Carles me mata xD, pero lo mismo a lgrtm le resulta interesante conocer el Code Coverage de PHPUnit http://www.phpunit.de/manual/current/en/code-coverage-analysis.html

Por otro lado, viendo un screencast de Carlos Ble, vi que tenía un widget que lanzaba los tests automáticamente con cada cambio... Lo más parecido que he podido encontrar para PHP (tampoco he buscado tanto) es esto, pero no mola lo mismo xD http://net.tutsplus.com/tutorials/php/automatic-testing-for-tdd-with-php/

No conocía la página

carlescliment's picture

No conocía la página net.tutsplus.com.

¡Está genial!

¡Gracias Jesús!

(habrá que probar el watchr)

Me estoy dando cuenta que

lgrtm's picture

Me estoy dando cuenta que tengo que darle caña a documentación, pero bueno poco a poco lo iré mirando que tambien tengo curro.
Gracias a todos por los links....

En twitter vi un post sobre libros a leer.
Estaría bien colocarlos akí tambien!!!

Se llega a tiempo para apuntarse uno?

pcambra's picture

No se si habéis empezado o no con la dinámica pero me gustaría apuntarme a ver si cojo el hilo :)
pedro.cambra at gmail

Genial Pedro, ¡bienvenido al

carlescliment's picture

Genial Pedro, ¡bienvenido al grupo!

En principio el martes nos veremos en un hangout para ir desarrollando entre todos la kata de este mes.

¡Gracias por participar!

Grbaciones.

lgrtm's picture

El otro día se nos escapo la grabación, para que no ocurra lo mismo, alguno tiene previsto o puede grabar la sesión en video?

Saludos.

Yo grabé un rato del martes,

pcambra's picture

Yo grabé un rato del martes, pero no lo tengo entero porque se me cayó la conexión...
¿hay un post para la sesión 2?

Yo grabe toda la sesión, así

lgrtm's picture

Yo grabe toda la sesión, así que nada más mueva esto Carles la subimos, él si comento de abrir un nuevo post.
La calidad audio no es muy alla pero se entiende perfectamente, el video es de la calidad que nos salio del hangout.

En general se puede ver.

Saludos.
Miguel

Spain

Group organizers

Group categories

Región geográfica

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: