Refactorización de test

59 views
Skip to first unread message

Francisco Calles

unread,
Feb 28, 2013, 5:12:08 AM2/28/13
to tdde...@googlegroups.com
Hola a todos,

Nos a surgido una pregunta desde https://tratandocon.wordpress.com y me gustaría saber que hacéis cuando usáis TDD.

A la hora de refactorizar ¿Refactorizáis los test?

Gracias por vuestras aportaciones.

Jose Raya

unread,
Feb 28, 2013, 5:14:18 AM2/28/13
to tdde...@googlegroups.com
Qué curioso, estaba refactorizando mis pruebas cuando he visto el correo :) En mi opinión, si no las refactorizas de vez en cuando al final se vuelven muy costosas de mantener.

Saludos,

Jose Raya

agilogy
>>| www.agilogy.com
C/ Bruc 42
08010 Barcelona
+34 93 354 11 78


2013/2/28 Francisco Calles <franc...@gmail.com>

--
Has recibido este mensaje porque estás suscrito al grupo "TDDev" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a tddev-sp+u...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a tdde...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/tddev-sp?hl=es.
Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
 
 

Alfredo Casado

unread,
Feb 28, 2013, 5:16:08 AM2/28/13
to tdde...@googlegroups.com
Claro, los test son código, hay que eliminar duplicación, poner buenos nombres, hacerlos más legibles etc,etc.

Juanma Gómez

unread,
Feb 28, 2013, 5:30:52 AM2/28/13
to tdde...@googlegroups.com
Efectivamente, nosotros también refactorizamos los tests

Fioddor Superconcentrado

unread,
Feb 28, 2013, 5:54:23 AM2/28/13
to tdde...@googlegroups.com
El 28 de febrero de 2013 11:12, Francisco Calles <franc...@gmail.com> escribió:
Nos a surgido una pregunta desde https://tratandocon.wordpress.com y me gustaría saber que hacéis cuando usáis TDD.

A la hora de refactorizar ¿Refactorizáis los test?

Sí y no:

Sí, los tests se refactorizan.
Pero no a la vez que el código a probar. Primero uno, luego el otro.

 

Pablo Rodriguez Monedero

unread,
Feb 28, 2013, 6:44:36 AM2/28/13
to tdde...@googlegroups.com
Los test son código, se pueden refactorizar para mejorar su mantenimiento y KISS.

NO se refactorizan cuando se refactoriza la aplicación. Al refactorizar el código de la aplicación, los test no hay que tocarlos, ya que la salida final tiene que ser igual y para eso están los test. Mejor no tocar los tests hasta estabilizar el código.

Un saludete


--
Has recibido este mensaje porque estás suscrito al grupo "TDDev" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a tddev-sp+u...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a tdde...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/tddev-sp?hl=es.
Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
 
 



--
-------------------------------------------
. Pablo Rodriguez Monedero                .
. http://dailycosas.net
.                                         .
.  "There are only 10 types of people:    .
.     Those who understand binary,        .
.     and those who don't"                .
-------------------------------------------

Leo Antoli

unread,
Feb 28, 2013, 7:22:20 AM2/28/13
to tdde...@googlegroups.com
Hola,
No veo la diferencia que ponéis entre cuando refactorizar código de producción y código de test.

Recuerdo que refactorizar significa cambiar el código más legible sin cambiar la funcionalidad, en particular refactorizar un tests significa hacerlo más legible, no cambiar lo que prueba el test.

Si hacéis TDD y aunque no lo hagáis, sólo se puede refactorizar cuando todos los tests están en verde. Si los tests no están en verde, en teoría sólo uno estaría en rojo y lo que haces es el menor código para que pase el test (a menos que el test esté mal porque hayan cambiado requisitos entonces cambias el test).

Dando por hecho que están pasando todos los tests, puedes refactorizar tanto código de producción como tests para hacerlos más legibles, en el orden que quieras.

Luego refactoriza todo lo que quieras (código producción y pruebas) mientras estén en verde los tests, eso sí, se hazlo en pasos pequeños (baby steps), para que si te cargas algo sepas donde mirar. Alguna vez puedes necesitar hacer una gran refactorización, pero será las menos veces.

Por supuesto refactorizar  sin la red de seguridad de tests automáticos es peligroso, te puedes estar cargando cosas que no esperas (efecto mariposa volando en Tokio).

Saludos,
Leo





2013/2/28 Pablo Rodriguez Monedero <pabl...@gmail.com>

Vicent Soria

unread,
Feb 28, 2013, 7:23:00 AM2/28/13
to tdde...@googlegroups.com
Estoy de acuerdo,

Yo nunca refactorizo los tests cuando estoy refactorizando el código de la aplicación. Aplico baby-steps también en ese aspecto.

Primero refactorizo una cosa, lanzo los tests, commiteo, y después refactorizo la otra, lanzo los test, y commiteo.

Así es más difícil que algo se rompa y perdamos valor.

Saludos.
Vicent Soria

Carlos Ble

unread,
Feb 28, 2013, 8:14:58 AM2/28/13
to tdde...@googlegroups.com
Hola!
Lasse Koskela ha vuelto a escribir un libro, esta vez sobre el cuidado con que hay que escribir y mantener los tests. Te lo recomiendo:


Saludos :-)


--
Has recibido este mensaje porque estás suscrito al grupo "TDDev" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a tddev-sp+u...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a tdde...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/tddev-sp?hl=es.
Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
 
 



--
Carlos Ble
www.CarlosBle.com - @carlosble 
Check out my book on TDD: www.dirigidoPorTests.com/el-libro
Try my latest app for team productivity: www.liveTeamApp.com
Need test doubles for python?: www.pyDoubles.org

Fioddor Superconcentrado

unread,
Feb 28, 2013, 8:15:15 AM2/28/13
to tdde...@googlegroups.com
El 28 de febrero de 2013 13:22, Leo Antoli <leo.a...@gmail.com> escribió:
No veo la diferencia que ponéis entre cuando refactorizar código de producción y código de test.
No hay diferencia. Hay interferencia (potencial).

 
Recuerdo que refactorizar significa cambiar el código más legible sin cambiar la funcionalidad, en particular refactorizar un tests significa hacerlo más legible, no cambiar lo que prueba el test.
Eso será si se refactoriza bien. Pero si probamos es precisamente porque la realidad no se ajusta a la teoría.
Si el mundo real fuese perfecto no haríamos TDD. Desarrollaríamos y todo iría bien a la primera.
Como no podemos fiarnos, probamos.


Dando por hecho que están pasando todos los tests, puedes refactorizar tanto código de producción como tests para hacerlos más legibles, en el orden que quieras.
El orden da igual, pero no se pueden refactorizar a la vez aplicación y los tests que la prueban. Refactorizas uno (el que quieras, y cuando lo tengas en verde refactorizas el otro.

Tomando tu analogía de la red: Se puede saltar y se puede soltar (la red. Por ejemplo para tensarla), pero no se puede hacer ambas cosas a la vez.

2013/2/28 Pablo Rodriguez Monedero <pabl...@gmail.com>
Los test son código, se pueden refactorizar para mejorar su mantenimiento y KISS.

NO se refactorizan cuando se refactoriza la aplicación. Al refactorizar el código de la aplicación, los test no hay que tocarlos, ya que la salida final tiene que ser igual y para eso están los test. Mejor no tocar los tests hasta estabilizar el código.

Leo Antoli

unread,
Feb 28, 2013, 8:41:07 AM2/28/13
to tdde...@googlegroups.com
Perdona, sigo sin ver la ventaja de refactorizar por separado tests y código producción.
Dando pasos pequeños puedes hacer una pequeña refactorización en código producción, luego en test, otra vez en test, producción, etc. Obviamente cada vez que haces una pequeña refactorización ejectutas los tests para ver que no te has cargado nada.

¿ estamos de acuerdo en que refactorizar se refiere a cambiar sólo el código para hacerlo más legible, no cambiar su funcionalidad o cambiar lo que prueba el test ?

¿ estamos de acuerdo en que hay que tener todos los tests en verde para refactorizar ?

Partiendo de eso, no entiendo que problema ves en refactorizar una cosita de un test, ejecutar todos los tests para ver que no te has cargado nada, refactorizar una cosita del código de producción y ejecutar todos los tests para ver que no te has cargado nada, etc.

Esto se aplique refactoricemos "bien" o "mal". Siempre que hacemos un pequeño cambio para refactorizar ejecutamos todos los tests (al menos los unitarios) para ver que no nos hemos cargado nada.
Por ejemplo lar refactorización de un código de producción normalmente se hará en pasos sucesivos, no en un gran cambio.

La refactorización se hace con la red puesta (con los test en verde), si en alguna refactorización te cargas la red, te paras y corriges para volver a dejar todo en verde antes de seguir refactorizando.

Saludos,
Leo



Saludos,
Leo






2013/2/28 Fioddor Superconcentrado <fio...@gmail.com>

Alfredo Casado

unread,
Feb 28, 2013, 8:46:42 AM2/28/13
to tdde...@googlegroups.com
Una cosa, por definición si que lo que haces es refactor (y no rediseño) es bastante complicado refactorizar a la vez test y producción, un refactor es un cambio pequeño y bien definido, en raras ocasiones un sólo refactor afecta al código de test y producción al mismo tiempo. Quizas alguna constante que uses en los dos sitios.

La idea es "un refactor -> pasar los test -> ...". Da igual donde sea el refactor.

Leo Antoli

unread,
Feb 28, 2013, 8:53:15 AM2/28/13
to tdde...@googlegroups.com
quizá no me espresé bien.

no digo en un solo refactor cambiar código de producción y test. Digo ir alternando refactors de tests y producción si quieres, no necesariamente hacer primero todos los refactor de producción y luego de tests.

haciendo el refactor en baby steps como dices es raro tener que tocar en código de producción y tests a la vez.

y por supuesto ejecutar los test en cada refactor para ver que sigues en verde.

Saludos,
Leo




2013/2/28 Alfredo Casado <casado....@gmail.com>

Enrique Amodeo

unread,
Feb 28, 2013, 9:45:58 AM2/28/13
to tdde...@googlegroups.com
No seamos demasiado estrictos. Yo me conformo con que la gente cuide el código de tests con el mismo mimo que el de producción, y que cuando hagan un refactor en el código de producción no cambien la funcionalidad (los tests vuelven a estar en verde).

Rediseñar el código de tests para hacerlo más mantenible es esencial, y hay que hacerlo de forma incremental. Pero realmente no podemos asegurar que este rediseño sea un refactor, ya que no tenemos tests para los tests. Pero si haces baby steps no vas a tener problemas con esto en la práctica.

Salud !


2013/2/28 Leo Antoli <leo.a...@gmail.com>

trikitrok

unread,
Feb 28, 2013, 6:39:32 PM2/28/13
to tdde...@googlegroups.com
Hola

Coincido con Enrique. 
Refactorizar (si se puede llamar así) código de tests es un refactoring "que se hace sin red", y por tanto es, en cierta manera, más peligroso.

Cuando refactorizó código de un test, intento volver a verlo fallar (ya sea modificando entradas o valores esperados, etc).

La razón por la que lo hago es, precisamente, que no existe ningún test que caracterice el comportamiento del test.

Esto lo aprendimos por las malas...
Trabajamos con simulaciones biofísicas, y tenemos test unitarios y de integración, para tener regresiones que 
"nos protejan de nosotros mismos" cuando refactorizamos.
El caso es que ha habido algunos refactorings de tests hechos con muy buena intención, en los que sin darnos cuenta introdujimos algún error,
que provocó que dichos tests empezaran a dar falsos positivos. 
Esto es, creías que el test hacía lo mismo porque todos los casos de test seguían en verde, pero en verdad el test ya no funcionaba.
Esto nos hizo un agujero en nuestra "red de seguridad" de tests de regresión.
A partir de ahí, se abrió la puerta al caos, porque seguimos refactorizando código de producción 
apoyándonos en un test que ya no testeaba correctamente durante un tiempo, hasta que una contradicción nos hizo replantearnos si el test todavía hacía lo que se suponía que estaba haciendo.

La estrategia que tomamos para intentar que nos nos pase de nuevo es verlos fallar de nuevo.

Con test sencillos y con aserciones simples, esto no es un problema, pero nuestros tests con moléculas
grandes a veces son verdaderos "mostruitos". 

Bueno, de todas formas soy un novato en esto, con lo que mejor tómense mi opinión "cum grano salis".

Saludos,
Manuel

Francisco Calles

unread,
Mar 1, 2013, 5:38:21 AM3/1/13
to tdde...@googlegroups.com
Gracias a todos por vuestras aportaciones,

Teniendo claro que el fin es tener un código legible y unos test que cumplan los principios  FIRST, al desarrollar con TDD hacemos que el código e incluso la arquitectura emerja de forma clara y natural.

A mi se me a dado el caso, sobre todo a la hora de hacer refactor, que ves como va creciendo el código y vas identificando patrones, arquitectura, relaciones ... entre las diferentes clases, librerías, mensajes, framewroks...

En este caso, en el que el refactor puede implicar cambiar las relaciones de las clases para añadir un patrón, cuando termino de hacer refactor de código, algunos test que antes estaban en verde ahora vuelven a estar en rojo, por lo que tengo que modificarlos y en muchos casos borrarlos ya que dejan de ser funcionales y su propósito lo absorbe otro test. (Con métodos privados)

Cuando tengo de nuevo todos los test en verde, refactorizo los test y reduzco la lista de test a medida que estos dejan de ser útiles.

Si tengo una calse de test con los TestMehtods que validan una clase y me doy cuenta de que esa clase entra a formar parte de un patrón que tendrá una Interface sobre una clase abstracta, creo una nueva clase de test para vaidar la Interface, y aunque dejo la clase de test que prueba la clase que ahora esta por debajo de la interface, en la mayoría de ocasiones los test unitarios que validaban la clase dejan de tener sentido, por lo que reduzco el numero de test.

¿Esto es refactorizar los test? ¿O es una ñapa de cuidado? 

Gracias a todos

Como se aprende sin ir al cole...


Angel Java Lopez

unread,
Mar 1, 2013, 6:01:48 AM3/1/13
to tdde...@googlegroups.com
Hola gente!

Francisco, interesante, y tambien interesante todo el hilo. Me quedan dos dudas:

> En este caso, en el que el refactor puede implicar cambiar las relaciones de
> las clases para añadir un patrón, cuando termino de hacer refactor de
> código, algunos test que antes estaban en verde ahora vuelven a estar en
> rojo, por lo que tengo que modificarlos y en muchos casos borrarlos ya que
> dejan de ser funcionales y su propósito lo absorbe otro test. (Con métodos
> privados)

Algun ejemplo de esto? En general, cuando hago refactor del codigo que
estoy armando, no se rompen los test.

Y con respecto a:

> Si tengo una calse de test con los TestMehtods que validan una clase y me
> doy cuenta de que esa clase entra a formar parte de un patrón que tendrá una
> Interface sobre una clase abstracta, creo una nueva clase de test para
> vaidar la Interface, y aunque dejo la clase de test que prueba la clase que
> ahora esta por debajo de la interface, en la mayoría de ocasiones los test
> unitarios que validaban la clase dejan de tener sentido, por lo que reduzco
> el numero de test.

No me pasa de agregar una interface, hasta que, por ejemplo, tengo DOS
clases concretas y alguna clase en concreto que puede usar una
instancia de esas dos clases. Digamos que armo:

- La clase A, con sus tests
- La clase B que consume a A, con sus tests
- etc...

Se nos da un caso de uso, donde lo que tiene que hacer A se resuelve
de otra manera. Entonces

- Escribo la clase A2 usando TDD, con tests

Ahora, abstraigo IA, la interfaz comun, A renombro a A1, y B en vez de
usar instancia de A, usa instancia de IA.

Y los tests siguen.

Pero nunca me aparece IA, hasta que no tengo A2 con TDD, con caso de
uso concreto.

Claro, todo esto en un lenguaje tipado con clases e interfaces. En
JavaScript, o Ruby, o Smalltalk, ni me aparece este caso (lo de crear
una interfaz) ;-)

Por que aparecen interaces en otros casos?

Angel "Java" Lopez
@ajlopez
github:ajlopez

2013/3/1 Francisco Calles <franc...@gmail.com>:

Francisco Calles

unread,
Mar 1, 2013, 6:25:35 AM3/1/13
to tdde...@googlegroups.com

> En este caso, en el que el refactor puede implicar cambiar las relaciones de
> las clases para añadir un patrón, cuando termino de hacer refactor de
> código, algunos test que antes estaban en verde ahora vuelven a estar en
> rojo, por lo que tengo que modificarlos y en muchos casos borrarlos ya que
> dejan de ser funcionales y su propósito lo absorbe otro test. (Con métodos
> privados)

>Algun ejemplo de esto? En general, cuando hago refactor del codigo que
>estoy armando, no se rompen los test.

Ej: Si veo que puedo implementar un patron, tengo que modificar las clases que intervienen en el y los permisos de accesibilidad de los métodos.




Angel Java Lopez

unread,
Mar 1, 2013, 6:45:02 AM3/1/13
to tdde...@googlegroups.com
Gracias por el detalle, Francisco, voy entendiendo.

Pero aun no me imagino un caso, o me cuesta imaginarlo. A ver,
recuerdo un caso mio de hace poco.

Tengo una clase que tiene que recibir un objeto, un mensaje digamos,
que tiene una estructura (nodos dentro de nodos, un arbol, digamos).
Como ese mensaje me lo envian de otra aplicacion, un caso de uso es:
rechazar los mensajes invalidos. Queda en algun test

processor.ValidateMessage(msg)

La primera implementacion, es ingenua. Un monton de if, metodos
anidados, etc, que fueron surgiendo con los test: probar un mensaje
vacio, un mensaje con un nodo, un mensaje con dos nodos anidados, un
mensaje con ... y asi. Puede que este bien y, decidimos en el equipo
lo dejamos asi. O puede que alguien sugiera: hagamos un Visitor, para
recorrer el arbol del mensaje, para hacer validadores del mensaje.
Puede que el visitor lo hagamos por refactor de la implementacion (y
vigilando a cada paso que los test anteriores sigan andando).

Al final, ponemos el visitor, pero no tuvimos que cambiar ningun test
de los ya existentes.

Habra un ejemplo concreto de agregar algo, un patron, lo que sea, que
implique que haya que rearmar los tests?

En mi jerga, refactor es cambiar la implementacion interna, pero el
ValidateMessage sigue igual, y la conducta vigilada por los tests,
sigue igual.

Lo que puede pasar, de tanto en tanto, es que tengamos redisenio:
cambiar la forma que vamos a consumir processor, por ejemplo. Pero no
se me ha dado eso por agregar un patron, sino, por descubrir, por
ejemplo, con nuevos casos de uso, que el mensaje ya viene validado o
algo asi. Es decir, surge escribiendo NUEVOS TESTS ante los nuevos
casos de uso. No por refactor. Pero imagino que debe haber un ejemplo
concreto. Esa es la duda que me queda entonces:

Ejemplo concreto de refactor que rompa los tests? Debe haber, pero sin
tener uno concreto, me es dificil ver cuando se da el caso.

Interesante tema!

Angel "Java" Lopez
@ajlopez

2013/3/1 Francisco Calles <franc...@gmail.com>:

Uzi Mamani Fernández

unread,
Mar 2, 2013, 9:49:09 PM3/2/13
to tdde...@googlegroups.com
Hola gente no veo otro tipo de refactoringn en Unit Test que la eliminación de codigo duplicado. ya que si partimos de que los Unit test deben ser simples sin  logica, entonces la refactorizacion solo seria la que menciono arriba.

porque si por un nueva caracteristica que me piden, eso hace que los test deban modificarse eso no es refactorización es mantenimiento de los test, eliminar los que  ya no sirven a los propositos o que pierden validez por cambio de las reglas de negocio. y eso es parte del mismo proceso de desarrollo y/o mantenimiento.

saludos cordiales

uZi

2013/2/28 trikitrok <trik...@gmail.com>



--
Saludos

uZi

About me
follow me on twitter  @uzigula
If you like check my blog  The Agile Road

Leo Antoli

unread,
Mar 3, 2013, 3:24:57 AM3/3/13
to tdde...@googlegroups.com
y por ejemplo no podrías poner un mejor nombre a un test ? 
Ten en cuenta que según vamos aprendiendo más del dominio vamos entendiendolo mejor y se nos pueden ocurrir mejores nombres, cambiar un nombre es un refactor.

Rainsberger decía que resumía el conseguir un diseño simple en quitar código duplicado y poner buenos nombres.

se puede hacer exactamente el mismo refactoring en los tests y en el código de producción. en ambos casos no se puede tocar funcionalidad, si no dejar de ser refactoring.


Lo que comentaba Enrique y Manuel de que el código te test no tiene red de seguridad, aunque me gusta el argumento no se si estoy de acuerdo con ello. Lo que si me gusta lo que comentaban de tratar el código de test con el mismo cariño que el de producción.
La gran diferencia que veo tocando tests es que quites comprobaciones (p.e. asserts) y que al no probar cosas los tests pasen porque haber quitado comprobaciones. Muy buena recomendación la que decía Manuel de cuando tocas cosas en los tests verlos en rojo para ver que de verdad prueban lo que quieres.

En teoría, si tienes buenos tests que prueba bien tu código de producción, si refactorizando te cargas algo del test debería fallar, si no falla es porque sigues cumpliendo los requisitos. 
El mismo problema lo podrías tener tocando código de producción, si no tienes buenos tests te podrías haber cargado algo y no darte cuenta.
Se complementan los tests y el código de producción para tener una buena red de seguridad y puedas tocar cualquiera de las dos cosas.

Sobre los tests tenemos que tener en cuenta que son "no falsables". El que pasen todos los tests no quiere decir que tu código funcione bien, pero si falla un test si significa que tu aplicación no funciona (por supuesto si el test prueba lo que quieres). 
Nunca podremos estar totalmente seguro de que nuestra aplicación funciona bien por muchos tests que tengamos, tenemos que hacer un análisis coste-beneficio para ver hasta que nivel de confianza (a cambio de un coste) queremos llegar.
Es como la tetera de Russell (o la existencia de Dios)  http://es.wikipedia.org/wiki/Tetera_de_Russell

Saludos,
Leo



2013/3/3 Uzi Mamani Fernández <uzi...@gmail.com>

Angel Java Lopez

unread,
Mar 3, 2013, 4:33:23 AM3/3/13
to tdde...@googlegroups.com
Hola gente!

Hmm... yo hago otro tipo de refactorizaciones. Para ir a un ejemplo
concreto, tengo la de ayer:

https://github.com/ajlopez/ClojSharp/commit/23c2fe80e5c19c453e6c16bc31bcd80ed0665560

Estaba armando un Lexer, que hasta ese momento solamente reconocia
nombres. Agregue un test de reconocer enteros. El metodo NextToken de
Lexer fue creciendo. Luego refactorice: distribui lo que tenia
NextToken en nuevos metodos NextName, NextInteger. Ahi hice el commit
(generalmente hago commit al final del ciclo rojo, verde, refactor,
asi que no se ve el paso de refactor (de NextToken grande a NextToken
con dos metodos auxiliares), pero pueden ver el resultado).

Angel "Java" Lopez
@ajlopez

2013/3/2 Uzi Mamani Fernández <uzi...@gmail.com>:

Leo Antoli

unread,
Mar 3, 2013, 5:07:49 AM3/3/13
to tdde...@googlegroups.com
Hola Angel,
era una simplificación lo de código duplicado y poner buenos nombres, la idea general es hacer el código más legible sin cambiar su funcionalidad. Pero con lo del código duplicado y nombres cubres muchísimo.
P.e. pondría en tercer lugar el conseguir que los métodos y clases no sean muy grandes.

por curiosidad, te estás currrando un lexer y/o parser a pelo en vez de usar p.e. antlr4 para c# ?
tenías un enum TokenType con un solo elemento ? yo hubiera esperado a tener al menos 2 elementos. 
El hacer un lexer es buen ejempo para hacerlo con TDD.

Saludos,
Leo



2013/3/3 Angel Java Lopez <ajlop...@gmail.com>

Angel Java Lopez

unread,
Mar 3, 2013, 5:34:56 AM3/3/13
to tdde...@googlegroups.com
Hola gente!

Leo, si, estoy haciendo el Lexer y el Parser a mano, usando TDD.
Siempre hago eso, si ven otros proyectos ahi en mi GitHub, nunca uso
un generador. Me parece tan facil hacerlo en TDD, y de esta forma, vas
realmente entendiendo como son los elementos del lenguaje que uno esta
implementando. El sistema va creciendo con "baby steps".

Buen punto Leo, lo de TokenType. Podria haberlo puesto despues.

Ayer me quede pensando en este hilo, y los refactor. Vi otro ejemplo
de refactor. Antes en este hilo mencionaba cuando aparecia una
interface en un lenguaje tipado. A mi me aparecio ayer, cuando hice
dos cosas:

- Implementar nuevo test
- Refactorizar para mejorar la implementacion

El resultado en:
https://github.com/ajlopez/ClojSharp/commit/51c678ece96d6d1cef92f36afda8d8fc711ffd8c

En ese interprete Lisp/Clojure que estoy armando, hasta ese momento,
una lista soportaba la evaluacion de algo como

(+ 1 2)

Solo con un Add como cabeza de lista. No soportaba nada mas. Ver en
ese commit, el codigo de List.cs que se saco.

Arme nuevos tests para que List soportara tambien simbolos:

(+ one two)

Ver en ese commit, lo que se agrego a ListTests.cs

Eso llevo a que tuviera que implementar lo que hasta ese momento no
tenia implementado: distinguir entre formas (normales) y formas
especiales (special forms) en Lisp.

(def one 1)

define una variable one, pero def no evalua los simbolos ANTES de ser
ejecutada. Es una special form. Y

(+ one two)

SI EVALUA sus argumentos ANTES de sumar. Todo eso llevo a la
aparicion, en varios pasos (en el commit solo se ve el resultado
final, incluso de algun fix de Source Analysis), de

IForm: para las forms Add y Def
BaseForm: para las forms como Add que evaluan sus argumentos ANTES de
ser aplicadas, y IEvaluable para todo lo que se pueda evaluar en un
contexto (por ahora el contexto tiene un diccionaro de nombre/valor,
para resolver por ejemplo el simbolo one a 1)

No tuve que cambiar los tests anteriores, sino que todo fue resultado de:

- Agregar dos tests
- Refactorizar la implementacion para no tener que soportar solo Add,
o solo Def, y asi.. (en algun momento habia puesto if (fn is Add) y
esas cosas, luego con el refactor, se fueron)

Finalmente, todo quedo en verde, los dos nuevos tests y los anteriores

;-)

Este es otro ejemplo concreto de refactor que se me ocurre, sin
cambiar los tests. Tal vez fue demasiado para un solo commit, pero
fueron varios pasos internos que derivaron por tener Add.cs y Def.cs
con diferente conducta.

Cuando tuve que implementar algo parecido en JavaScript, no necesite
de las interfaces IForm y demas. Creo que lo hice de otra manera:

https://github.com/ajlopez/AjLispJs

Nos leemos!

Angel "Java" Lopez
@ajlopez


2013/3/3 Leo Antoli <leo.a...@gmail.com>:

Angel Java Lopez

unread,
Mar 3, 2013, 6:46:18 AM3/3/13
to tdde...@googlegroups.com
Ah! Disculpen, ahi entendi, Uzi se refiere a:

> Hola gente no veo otro tipo de refactoringn en Unit Test que la eliminación
> de codigo duplicado. ya que si partimos de que los Unit test deben ser
> simples sin logica, entonces la refactorizacion solo seria la que menciono
> arriba.

a refactoring del codigo de los TESTS. Yo habia entendido refactoring
cuando hacemos (Unit) Test, en el proceso de TDD.

Si, de lejos el mas comun que he encontrado en ese caso es la
eliminacion de codigo duplicado. Tambien se da ahi, que si tenemos un
framework de test que soporte Initialize y Teardown por metodo de
test, pongo ahi mucho del codigo que he visto duplicado (mucho de
Arrange comun a todos los test de un grupo).

Otro es el que menciona Leo, el cambiar el nombre de un test.

Yo tambien suelo hacer (en lenguajes tipados, con clases, como C# o Java)

- Una vez que tengo una clase con varios tests, la divido en dos o
mas, porque voy descubriendo que es mas entendible para quien venga,
ver que hay tests que se agrupan por su parecido. Por ejemplo, si
tengo ya varios metodos sobre List, puede que hayan quedado 4 sobre
una Empty List, y esos los muevo a una nueva clase de test

Otras veces no, ya me doy cuenta que voy a encarar una serie de tests
sobre Empty List y armo la clase de test desde el vamos.

2013/3/2 Uzi Mamani Fernández <uzi...@gmail.com>:

Uzi Mamani Fernández

unread,
Mar 4, 2013, 8:44:00 AM3/4/13
to tdde...@googlegroups.com
Concuerdo con Angel para mi refactoring es mejorar el codigo, hacerlo mas testeable, mas legible, mantenible y claro que se ejecute eficientemente, pero los Casos de Uso siguen siendo lo mismos y por ende los test deberian estar todos en verde, si se rompen es que algo en el proceso de refactoring se nos olvido o hicimos mal.

Alguno a leido sobre NFTDD  - Non Functional Test Driven Development?

Saludos

uZi

2013/3/3 Angel Java Lopez <ajlop...@gmail.com>
Ah! Disculpen, ahi entendi, Uzi se refiere a:
Reply all
Reply to author
Forward
0 new messages