martes, 21 de septiembre de 2010

Capítulo 2.2.3 Hacer pasar la primera prueba

2.2.3 Hacer pasar la primera prueba

No tenemos mucho código todavía pero, hemos realizado una serie de importantes desiciones de diseño. Tenemos una clase de plantilla que carga una plantilla de texto que recibe un argumento al constructor, nos permite establecer un valor para un llamado marcador de posición y puede evaluarse a sí misma, produciendo la salida deseada. Tenemos listo el esqueleto del la clase Template, que se muestra en el listado 2.5 de modo que nuestro test compile.
Todos los constructores y métodos existen para hacer que corra el compilador pero, ninguno de sus constructores y métodos está haciendo nada hasta ahora. Hemos escrito una única prueba en su defecto que nos muestre un camino a seguir, hemos añadido lo suficiente al código de producción para hacer que la prueba compile.
¿Cómo hacemos que la prueba pasé y se ejecute rápidamente? La evaluación de una plantilla así de simple "Hola, $(nombre)" , con una cadena operación de reemplazo, como se muestra en el listado 2.6

Por ahora omiteremos dos declaraciones de importación de los listados de prueba pero, serán necesarias para acceder a la biblioteca JUnit.

Para ahorrar espacio, a partir de ahora vamos a omitir las dos declaraciones de importación de los listados de la prueba. Vamos a ampliar nuestra prueba para exprimir la aplicación que estamos buscando.

2.2.4 Escribiendo otra prueba

En el listado 2.7 nos muestra un camino para extender el código existenteHemos añadido una segunda llamada para establecer diferentes entradas y una segunda afirmación para verificar el objeto Template - que evaluaremos con la del úntimo valor en la variable "name". Nuestro código duro , el método evaluate en la clase Template es seguro que no pueda correr. Esta técnica es llamada triangulación, referente a como utilizamos múltiples entradas para llevar a la aplicación a una correcta implementación.

Podríamos denominarlo juego difícil pero relamente nos puede ayudar a evitar invación de características y exceso de ingeniería. Ahora cómo podríamos hacer ejecutar esta prueba? Vé usted un aforma de evitar que analizar el template actual? Vamos a ver a donde iremos con el código , como se ilustra en el listado 2.8
Al ejecutar nuestra prueba llegamos con el mismo resultado. Evidentemente nuestro test no es suficiente, sin embargo, tenemos que modificarlo, por lo tanto, debemos seguir triangulando para sacar las salidas literales de nuestro código. En el listado 2.9 muestra cómo podemos alterar nuestro test para que no sea sólo código duro.La barra roja nos indica que nuestro código duro entrega una declaración no determinada. En este punto nos vemos enfrentados a la tarea de analizar el template de texto de alguna forma. Tal vez , primero se deba aplicar la lógica de análisis y luego volver a la prueba. Es aquí que debemos hablar de amplitud y profundidad.

2.3 Primero anchura, primero profundidad

El código que construímos no es trivial como para realizarlo en un par de horas.
En nuestro template de ejemplo, acaba de llegar a un punto en que se descubre una complejidad que todavía no atendemos.

Cómo puede recordar en los algoritmos, hay una manera de recorrer un árbol, esto es por amplitud o por profundidad. Lo mismo se puede decir en el desarrollo basado en pruebas. En las figuras 2.3 y 2.4 compara las dos alternativas.

Podríamos decidirnos primero por la amplitud, escribir las pruebas contra la interfaz pública de la clase del template como se observa en la figura 2.3
La otra opción sería volver hacia atrás a un estado de trabajo y empezar a escribir test para el parseo del template, en lugar de análisis. Es decir, recorrer la funcionalidad primero en profundidad y aplicar los primeros detalles de un corte vertical antes de continuar con el corte siguiente, como se muestra en la figura 2.4 un enfoque similar.

En el caso de nuestro motor de template tiene "Hola, $(nombre)", podemos pasar por el menor nivel de funcionalidad- parceando el template - antes de agregar más funcionalidad (más pruebas) y ver donde vamos a llevarnos.

2.3.1 Detalles falsos una pequeña distancia.

En primer lugar, tendremos que empezar a almacenar el valor de la variable y template de texto en alguna parte. También se necesita hacer "evaluate" reemplazarlo en marcar el valor de la posición. EL lista 2.10 muestra una manera de conseguir que nuestro test pase.
Algunos podrían decir que estamos trampeando el código duro en una expresión regular "${name}". Realmente no es hacer trampa, sin embargo. Estamos siendo disciplinados y no queremos tentarnos en sólo escribir el código, sino dar pasos pequeños para que todas las pruebas corran en terreno estable.

Ahora lo que se viene es la refactorización. Vés algo para refactorizar? Se observa alguna duplicación? En concreto, manejar código duro con nombre variable. Que mejor manera que hacerlo mediante la introducción de múltiples variables.

2.3.2 Minimizando los falsos pasos

Es hora de escribir una prueba con múltiples variables en un template.

Esta prueba que ha fallado, nos dice que retorna en "evaluate" texto, en lugar de 1,2,3 (lo que no es sorpresa porque nuestra expresión regular busca "$(nombre)"). La gran pregunta es qué hacer con nivel de código añadido.

Una manera en que viene a la mente- para obtener un caso de prueba que pase rápido - sería buscar el reemplazo de operación para cada una del par de variables nameValue donde el template lo reconozca. Esto podría ser lento, y podría haber algún problema con los valores de las variables que contiene subcadenas que se parecen a "$(variable)" pero que debe ser lo suficientemente bueno para nosotros ahora mismo. Por lo general , cuando pienso en preocupaciones o deficiencias como la que con el planteamiento de expresiones regulares que estamos hablando.
Cuando nos encontramos con que, por ejemplo, algo está mal aplicado o faltan completar, estamos trabajando en un caso de prueba. Ahora , vamos a ver cómo podríamos aplicar la búsqueda y reemplazo ha nuestra ejecución de prueba.

Detalles nuevos y mejorados

La implementación basada en búsqueda y reemplazo es mostrada en el listado 2.11 que corra sin defectos.
Nos queda las siguientes pruebas por hacer:

  • La evaluación del template para "Hola, $(nombre)" sin valor en la variable "nombre" plantea un MissingValueError.
  • La evaluación del template "Hola, $(nombre)" con valores "Hola" y "Reader" para las variables "DoesNotExiste" y "name", respectivamente, tienen como resultados "Hola" y "Lector".
  • Evaluar template con los valores "$(un), ($ dos), () tres ", tiene como resultados respectivos "1", "$(foo)" y "3" y comprobar que hace el template con el resultado "1$(Foo), 3"
Testing para casos especiales

En el siguiente fragmento introduciremos un nuevo caso para variables que no existen en el template, las variables son ignoradas por la clase template.
Ahora nuestro caso de prueba pasa, no es asi?

Nuestro IDE ejecuta los test tan rápido cada vez más pero no al 100%. Por eso que tal vez es mejor considerar la ejecución con resultados en rojo antes de ver resultados en verde.

2.4 No nos olvidemos de refactorizar.

Aún que no hemos añadido código de producción veamos que podemos hacer con nuestro código. El listado 2.12 plantea en nuestra clase como está ahora.
Tómese un momento para pensar sobre lo que podría mejorar en el código de prueba. La duplicación semántica. Cualquier cosas que salte a la vista. O que se pudiera limpiar. Vamos a seguir cuando esté listo para comparar notas.




No hay comentarios:

Publicar un comentario