jueves, 23 de septiembre de 2010

Definición Criterio "LISTO"

Una tarea en desarrollo se considera listo cuando:
  • Se realizarón los Test Unitarios (según acuerdo del equipo de trabajo).
  • Se realizó per-review de los Test Unitaros (JUNIT, TDD)
  • El Proyecto compila exitosamente.
  • Hudson deploya exitosamente las versión del día.
  • La solución funciona en distintos exploradores , determinado por el cliente (IE6, IE7, IE8, FF 3.5, FF3.6, Chrome, Safari, etc).
  • Los criterios de aceptación por parte del Cliente son OK.
Un plan de pruebas se considera listo cuando:
  • Los Escenarios seleccionados responden a los requerimientos definidos por el cliente.
  • Los Casos de pruebas construídos, responden a los requerimientos definidos por el cliente y objetivos del las historias (scrum).
  • Los Casos de pruebas construídos, contienen las validaciones básicas.
  • Los Casos de pruebas construídos contienen las validaciones genéricas de servicios internos (WS, Tomcat, Maden, servidor de correo, etc).
  • Los Casos de pruebas construídos contienen las validaciones genéricas de servicios externos.
  • El plan de prueba fué revisado por el equipo de trabajo (per-review).

Una Certificación se considera listo cuando:

  • La ejecución manual del plan de prueba alcanza el porcentaje exitoso (métricas exitosas).
  • La ejecución automatizadas (selenium) del plan de prueba finaliza exitosamente.
  • El porcentaje de éxito alcanzado por las métricas es mayor igual a 98% .

miércoles, 22 de septiembre de 2010

Capítulo 2.4.1 Refactorizando el código potencialmente.

2.4.1 Refactorizando el código potencialmente.

En primer lugar, todas nuestras pruebas utilizan objeto del template, por lo tanto deberíamos declarar la instancia una vez y no varias veces como se ha visto. En segundo lugar, estamos llamando al método a evaluar varias veces como un argumento. En tercer lugar, estamos instanciando la clase del template con la misma plantilla de texto en dos lugares. Esa es la duplicación y , probablemente se deba quitar.
Sin embargo, una de las pruebas está utilizando un template diferente de texto. ¿Debemos utilizar dos variables ejemplo, uno para cada pplantilla de texto? Si es así, quizas sea conveniente dividir la clase en dos para hacer frente dos partidos.

Nota: Un accesorio es un conjunto de variables de instancia.

Existe otra alternativa para la división de la clase con TestTaemplate. Vamos a ver la otra alternativa de refactorización.

2.4.2 Eliminación de una prueba redundante

Hay un tipo más fundamental de la actual duplicación de nuestro código de prueba oneVariable, differentTemplate y multipleVariables. Si lo pensamos el último método abarca los anteriores. El primero tambien abarca todas las combinaciones por lo tanto podemos deshacernos de la versión dejando una sola variable,. También se suma una nueva prueba para verificar que podemos establecer un nuevo valor para volver evaluar el template. Podemos ampliar a una variable desconocido VariabeAreIgnored utilizando la misma plantilla de texto como multipleVariables. Y vamos a ver lo que el código de prueba se muestra en la lista refactorizada 2.13.
Como se puede ver, hemos sido capaces de moldear nuestras pruebas a utilizar en un sólo modelo de texto configurado, dejando a los 4 métodos de ensayo. Ahora podemos ver el manejo de errores.

2.5 Agrengando un poco de control de errores

Este es el momento de añadir una nueva prueba.

2.5.1 Esperando una excepción

¿Cómo escribir una prueba unitaria que lanze una excepción? Con el constructor trycatch, por supuesto, sólo que esta vez , el código de una excepción es una buen caso- el comportamiento esperado. Como se muestra en la lista 2.14 , es un patron común para la excepción del test - ejecutado con JUnit
Nota : Tenga en cuenta la llamada al método después de dejar evaluar correctamente. Con ese llamado a org.junit.Assert#fail, decimos básicamente, "si llegamos hasta aca, es que algo salío mal" y el método no falla en la prueba. Sin embargo llamamos al método "evaluate". La hacer click en aceptar, tenemos una prueba que está fallando, aunque antes ni siquiera compilaba, pero añadiendo una clase MissingValueException vacío hace que desaparesca
Veamos la lista 2.15 para ver la mejora del código anterior.
2.5.2 Refactorizando pequeños métodos

Existen diferencias en el tamaño de los métodos, clases , etc. En el listado 2.16 muestra una versión de refactorización del método "evaluate"2.5.3 Mantener el equilibrio en los métodos

Una característica de un método es la coherencia de abstracción del código. Veamos el siguiente ejemplo.El método se evalúa haciendo dos cosas: sustituir las variables con valores y comprobar los valores que faltan en un nivel diferente de abstracción. La iteración "for" es claramente más complicado que la llamada al método checkforMissingValues. A menudo es fácil agregar pedacitos de funcionalidad pegando en línea a un método ya existente, pero sin perder de vista la incosistencia en nivel de abstracción, el código es un poco ininteligible.

Veamos en la lista 2.17 una simple aplicación de la refactorización del "método de extracción".
Ejecutamos nuesttos casos de pruebas, y nos damos cuenta que no se obtubo ningún problema con la refactorización. Hacer este tipo de ediciones en el código de trabajo sería un gran esfuerzo, sino tuvieramos la batería de casos de pruebas en nuestra espalda. Ahora falta un mensaje significativo para la excepción.

2.5.4 Detalles para una excepción.

Mientras escribe la prueba para el valor que falta, sólo se alcanzó a llamar una vez a la excepción MissingValueExcepction. O a veces usted a visto varias veces un mensaje que ni siquiera tiene un sentido informativo con sentido. Quizas lo que falte es agregar un valor al mensaje de la excepción. Observe el listado 2.18.Como de costumbre, editar y ejecutar un caso de prueba sólo toma unos minutos. Esta vez, usamos una API java.util.regex un poco diferente cone l fin de extraer el resultado que coincide con el patrón de la variable. Se explica mejor en la siguiente fracción de código.
Como de costumbre, la edición para la toma de un pase de prueba es una cuestión de un par de minutos.

Esta vez, tenemos que usar el API java.util.regex un poco diferente con el fin de extraer la parte del resultado renderizado que coincide con un patrón variable. Tal vez un fragmento de código que podría explicar mejor:
2.6 Cabos sueltos en la lista de casos
Hemos implementados todos los casos de prueba que proposupimos en el principio. Sinembargo, descubrirá algunos problemas con la implementación actual. Primero, no maneja valores de variables tales como delimitadores como "$("y")". Una de las pruebas restantes es el rendimiento a nuestra lista de casos.

  • Evaluar el template con los siguientes variable "$(un), $ (dos), () tres" con los valores "1", "$(foo)", y "3", respectivamente, y comprobar que el template hace que la ejecución resulte como "1,$(Foo),3".
  • Compruebe que un template de 100 palabras y 20 variables con valores 15 caracteres cada uno se evalúa en 200 milisegundos o menos.

2.6.1 Pruebas de rendimiento

Para tener una idea de si nuestra ejecución del template es correcta en cualquier performace, vamos a añadir una prueba rápida para evaluar el desempeño y asi ver si estamos cerca de un plazo de ejecución razonable. Esto se plantea en el listado 2.19.
Parece que nuestra aplicación de template no pasan la prueba de rendimiento para que se ejecute en 100 milisegundos para una template de 100 palabras con 20 variables. Sin embargo es bueno saber que se está gastando presuepuesto en el rendimiento. Ahora que sabemos que lo que está en su lugar , sabremos de inmediato cuando un cambio haga más lenta la ejecución.

2.6.2 Acercándonos al final del diseño.

En cuanto a la prueba restantes para los valores de las variables "$("y")", comienzan a ser más difícil ya que el trabajo de búsqueda y reemplazo no es tan simple de realizar. Además , no podemos confiar que nuestro método de detecciñon de variables no definidas mediante la búsqueda "${ }" sea un buen resultado.

Antes de seguir adelante, vamos a para toda estas especulaciones y escribiremos una prueba que denuestra si nuestras suposiciones sobre el comportamiento alctual del código es correcta. Agregar el siguiente caso de prueba en la clase TestTemplate, como se muestra a continuación:
La ejecución de nuestra prueba nos dice que ciertamente tenemos un problema. Esta prueba está arrojando un IllegalArgumentException desde el código de expresiones regulares. Es momento de volver fuera de la prueba, levantar el bloc de notas y dibujar un poco. En su lugar, vamos a resumir el capítulo hasta este momento, para comenzar con el siguiente capítulo.

2.7 Resúmen

El desarrollo basado en pruebas es una técnica poderosa que nos permite escribir mejor el código de un software y su ejecución se a más rápida. Lo hace centrádose en las necesidades del momento, haciendo que el trabajo presente pequeñas muestras, finalmente limpiar cualquier código que ensucie la funcionalidad, de mantenenimiento efectivo la salud de la base de código. En este ciclo primero es la escritura de la prueba, para que pueda ser ejecutado sin problemas, finalmente se realiza la refactorización del diseño que permite hacer un uso intensivo de la programación en la redacción de la prueba como si la prueba real exista y con una herramienta para creación de útiles diseño.

En este capítulo , hemos visto TDD en acción y no hemos dado cuenta que nuestro diseño actual del template no termina con un buena ejecución. Nos propusimos escribir un motor de template basado en una pequela lista de casos que apuntan al comportamiento esperado por el motor y seguimos un set de pruebas de código factorizado (rojo-verde-verde). Una vez que el código cumpla la mayoría de nuestro requisitos somos capaces de tomar decisiones más rápida en el avence de las pruebas y no tenemos miedo a refactorizar.

Ahora , vamos a voltear la página para el siguiente capítulo y ver cómo podemos superar las cuestiones pentiendes y concluir el motor de template funcionalmente, quedando una bonita pieza de producto.



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.




miércoles, 15 de septiembre de 2010

Softwate Quality Assurance, Software Defects

Finalidad:

El objetivo que persigue el aseguramiento de calidad es producir software de calidad.

¿Que és Calidad?

Calidad se refiere a todo el proceso del desarrollo de software, y está determinado por factores directos e indirectos. No es un concepto fácil de manejar, su complejidad se debe a que es multifacético ya que, puede ser descrito desde diversas perspectivas.

¿Cuales son esas perspectivas?

  • Desde un punto de vista trascendental, Calidad es reconocida pero no definida.
  • Desde un punto de vista del usuario, es un grado de adecuación al propósito.
  • Desde un punto de vista del productor, es una conformidad con la especificación.
  • Desde un punto de vista del producto, está ligada a características inherentes del mismo.
  • Desde un punto de vista en valor, ¿Cúnato el cliente está dispuesto a pagar?
¿Qué es SQA?

Software Quality Assurance, son acciones sistemáticas y planificadas para asegurar la calidad de software.

¿Cúal es el objetivo de SQA?

SQA tiene el propósito de planificar, desarrollar y controlar el proceso de verificación y validación (V&V).

¿Qué métodos posee para aplicarlo?Aplicación de métodos,
  • Revisiones e inspecciones ,
  • Testing,
  • Aplicación de estánderes,
  • Control de Cambios,
  • Mediciones,
  • Registro.
¿Qué es Validación (V&V)?

Existen conceptos:

  • La Verificación que permite responder a la siguiente pregunta ¿estamos construyendo el producto correctamente?
  • La Validación, que permite responder a la pregunta ¿estamos construyend el producto correcto?
¿Qué ganamos con las revisiones de software?

Las revisiones de software actúan como filtros que permiten descubrir en forma temprana los defectos de éste. Un descubrimiento temprano de los defectos permite evitar un gran impacto en los costos de testing y mantención.

Los defectos de software presentan un efecto de amplificación. Esto quiere decir que si los defectos no son detectados a tiempo, ellos son excelentes postulantes a alterar otras funcionalidades que se funcionaban correctamente o simplemente el software se limita a su objetivo principal.

¿Cúal es le objetivo de las revisiones de software?

  • Detectar defectos en la lógica, función o implementación.
  • Otros beneficios gratuitos, son verificar la satisfacción de requerimientos, asegurar cumplimiento de estándares, fomentar uniformidad y hacer proyectos más manejables.
¿Qué pasos se debe realizar para una revisión de software?

  • Definir tamaño, conformación y duración.
  • Revisar producto, no productor
  • Establecer agenda
  • Limitar debates y rebates
  • Enunciar problemas, no resolverlos
  • Llevar registro.
¿Qué acciones se debe realizar para una revisíon de software?

  • Limitar tamaño del grupo.
  • Exigir preparación previa.
  • Definir Checklist.
  • Asignar recursos.
  • Entrenar a los revisores.
  • "Revisar las revisiones".

martes, 14 de septiembre de 2010

UML

www.org.com/technology/uml
Ésta es la página de recursos UML del Grupo de Administración de Objetos (OMG, por sus siglas en inglés),
el cual proporciona las especificaciones para varias tecnologías orientadas a objetos, como UML.

www.smartdraw.com/resources/centers/uml
Este sitio muestra cómo dibujar diagramas UML sin utilizar herramientas para modelar.

ww.rational.com/uml
Ésta es la página de recursos UML de Rational Software Corporation; la empresa que creó UML.

microgold.com/Stage/UML_FAQ.html
Este sitio proporciona la FAQ UML que mantiene Rational Software.

ww.softdocwiz.com/Dictionary.htm
Este sitio contiene el Diccionario del Lenguaje de Modelado Unificado (Unified Modeling Language Dictionary),
el cual enlista y define todos los términos utilizados en UML.

Capítulo 2 - Comencemos con TDD

En este capítulo , desarrollaremos más comprensión de lo que es TDD y el secreto ( y no tan secretos) de sus ingredientes que lo hacen funcionar. Realizaremos los pasos siguientes después de haber escrito código de prueba. aprendiendo en el transcurso. Escribiremos pequeñas pruebas, eliminando los comportamientos paso a paso y refactorizando nuestro código sin piedad.

Agregaremos y eliminaremos códigos, Modificando el código de manera que podamos quitar código. A lo largo del camino, vamos a introducir a aplicaciones robustas y capaz de un motor de plantillas, incluyendo algunas funciones de control de excepciones para seguir una conducta al camino "feliz". Se discute cómo amenudo hay dos caminos posibles, anchura y profundidad.
Usted deberá tener una comprensión mucho mejor de cómo funciona TDD en la práctica y qué tipo de trucos seguiremos con el fin de movernos con más rapidez hacia el objetivo de un sistema de funciones completas.

Comenzaremos con el desarrollo de software real que utiliza TDD. Vamos a desarrollar un motor de template que pueden convertir las plantillas que contienen las variables y que son completadas en forma de lista en tiempo de ejecución Considerando que el primer paso en TDD es escribir un defecto de prueba , tenemos que averiguar la conducta deseada que nos gustaría probar.Tendremos una charla rápida sobre cómo llegar de un requisitos abstractos a las pruebas concretas.

2.1 Desde los requerimientos a los test

Imagine que usted tiene que implementar un subsistema para la colaboración de una corporación de software y en responsable de proveer plantillas de correos funcionales para los asistente de CEO para que puedan enviar todo tipo importante de documentos , personalizados con sólo dar doble click en el mouse.Qué pruebas realizaría en el desarrollo de dicho subsistema? Vas a conocer esta respuesta al leer este capítulo , cómo con cualquier sistema descomponeremos los requisitos en algo más pequeño y más concreto.

2.1.1 Descomposición de requerimientos.

Teniendo todos los requisitos previstos para el subsistema, tenemos que hacer una lista de lo que necesitamos hacer, denominadas tareas, ahora borra en forma momentánea las tareas de tu cabeza y hagamos todo de nuevo. Recortemos los requisitos en un conjunto de pruebas. ¿Puedes pensar en estas pruebas? a puesto que si ha pensado en un grupo de pruebas.

Una plantilla de correo sin variables de entrada es enviado. El marcado de posición para el nombre destinatario en un saludos reemplazaría por cada nombre de los destinatarios. Luego usted tendrá un montón de pruebas, que en conjunto comprobaría una parte del conjunto. Con el tiempo, tendrá cubiertos las expectativas del comportamiento del producto.

Para aclarar la diferencia entre tareas y test, la figura 2.1 contrasta algunas de las descomposiciones posibles de la plantilla de correo en tareas y test, respectivamente. Descompondremos las tareas (columna izquierda) donde lleva los elementos que hacen representativos el software producido. La columna de la derecha es la columna de pruebas, que representa las capacidades del software.

Las tareas sólo nos dan una idea de lo que debemos hacer. Veremos más ejemplos de los requisitos en descomposición en las pruebas en lugar de tareas.

2.1.2 ¿Qué buenas pruebas podemos hacer?

Hay algunas pautas que podemos utilizar para determinar si estamos escribiendo buenas pruebas. Hay un montón de reglas para la ejecución técnica de una unidad de prueba. Desde la perspectiva de la descomposición de requisitos en las pruebas, existen dos propiedades importantes que se identifican:
  • Una buena prueba es atómica.
  • Una buena prueba es aislada
Estas propiedades nos quiere decir que una buena prueba debe ser una prueba pequeña, focalizada, atómica, que separa la conducta deseada y que la prueba debe ser aislada de otras pruebas.

2.1.3 Trabajando a partir de una lista de pruebas

Procedemos a generar una lista de pruebas, de las que eligimos una , las más representativa en avance con el menor esfuerzo. Luego empezaremos por escribir el código de prueba. Vamos a ir tan lejos como para compilar y ejecutar la prueba antes de pensar en escribir el código de producción.

2.1.4 Programación por intento

Cuando se está escribiendo pruebas antes de que el código pase a producción, se enfrentan a un dilema: ¿Cómo probar algo que no existen sin romper las normas de ensayo de sesiones?. La respuesta es muy simple, imaginar que el código que se está probando, existe!!.

¿Cómo eso es posible? ¿Qué se supone que debemos pensar? Nos imaginamos una forma ideal en el código de producción desde el punto de vista de esta prueba en particular. ¿No es hacer trampa?. Si, lo estamos engañando, nos encanta¡ Usted escribe las pruebas suponiendo que el código de producción es tan fácil de usar como lo que nos imaginamos.
A esto se le denomina Programación por intento. Programación por intento es el concepto de la escritura de código, cómo si existiera otro trozo de código.

Ahora sabemos que debemos dividir nuestras necesidades en pequeñas pruebas centralizadas en lugar de tareas, ahora podemos entender que la lista de pruebas es una lista de programación por intento, este el momento de desarrollar una plantilla de tipos de pruebas con motores de sesiones.

2.2 Eligiendo la primera prueba.

Lo prometido, desarrollaremos un motor de plantillas basado en pruebas. Nos concentraremos entonces, en la lógica de negocio para el motor de las plantillas y no preocuparnos de todo el sistema.

TIP: En este punto, se recomienda un IDE favorito para desarrollar el motor de plantillas paso a paso.

El motor de plantillas tiene que ser capaz de leer en una plantilla, es decir, ser capaz de leer un texto estático con un número arbitrario de marcadores de variables de posición mezcladas con variables marcadas con una sintáxis específicas. Pero primero, debemos de hacer la plantilla, donde hay que dar valores para la variable nombre.

Lo primero que tenemos que hacer es porcesar la descripción del motor de la plantilla, en una lista inicial de las pruebas, a continuación , elija uno de ellos que deba aplicarse.

2.2.1 Creando una lista de pruebas

Antes que todo, debemos plantear el conjunto de requisitos para el subsistema de la plantilla de correo

* El sistema reemplaza los marcadores de posición variable como $ (firstname) y $ () apellido a partir de una plantilla obtenidad con el tiempo de ejecución.
* El sistema intenta enviar una plantillas con algunas variables no pobladas (variables en null), esto generará un error.
* El sistema ignora los valores de las variables que no se encuentran el la plantilla (validación de entradas o en los campos template).
* El sistema es compatible con el carácter completo Latin-1 establecido en las plantillas.
* El sistema es compatible con el caráter completo Latin-1 situado en valores de las variables.
* Y así sucesivamente.....

He aquí un intento de convertir a la plantilla de correo, los requisitos del subsistema de pruebas adecuadas:

* La evaluación del template "Hola, $ (nombre)" con el valor "lector" de la variable "El nombre de" resultados en la cadena "Hola, lector".
* La evaluación del template "$() saludo, $(nombre)" "Hola" y "El lector" respectivamente, los resultados en la cadena "¡Hola! Reader".
* La evaluación del template "Hola, $(nombre)" sin valor para la variable "nombre" no indica que debemos emplear un MissingValueError.
* La evaluación del template "Hola, $(nombre)" con valores "Hola" y "Reader", resulta en las variables "DoesNoExit" y "nombre, respectivamente, en la cadena "Hola, lector".
* Y así sucesivamente...(podríamos , por ejemplo, incluir algunos ejemplos concretos que serviría como prueba de que el sistema se ocupa de caracteres Latin-1)

Observa la diferencia? Las necesidades se han transformado claramente en un grado más concreto, más ejecutables. Con estas pruebas no hay necesidad de preguntarse por ejemplo, lo que significa "elevar un error" y suponiendo que significa una excepción ¿qué tipo de excepción que debería ser y lo que el mensaje de excepción debería decir?. Las pruebas nos dicen qué excepción MissingValueError deberíamos lanzar para un error específico.

Con este tipo de prueba, estamos en condiciones de producir respuestas binarias para la pregunta "estoy listo?". La lista de prueba es un documento de trabajo donde añadimos nuevas pruebas sobre la marcha.

Tenemos una lista de pruebas que nos dicen exáctamente cuando los requsitos se han cumplido. A continuación , empezaremos a trabajar con la lista haciendolos correr uno por uno.

2.2.2 Escribiendo el primer defecto de prueba

Tomemos la primera prueba de la lista y ver cómo podemos escribir el test antes del código.

Esta es nuestra prueba nuevamente:

La evaluación del template, "Hola, $(name)" el valor "lector" de la variable "El nombre de" resultados en la cadena "Hola, lector"

Nota: En este usaremos el IDE para escribir algo de código. Usaremos JUnit 4, la última versión de framework de pruebas unitarias para JAVA (htpp://www.junit.org). Si no estas familiarizado con JUnit leer el apéndice A para una breve introducción. El objetivo es ver la programación por la intención en la acción.

Porque vamos a poner en práctica la primera prueba, vamos a emprezar por dar un nombre a nuestra clase de prueba , en el listado 2.1


El código del listado 2.3 es lo que podríamos escribir para una prueba, suponiendo que la aplicación está ahí (aunque no lo es) la libertad para diseñar la plantilla en función de una manera más fácil de usar.
En el método de ensayo del listado 2.3, crea en primer lugar un objeto que al pasar por la plantilla de texto como un argumento de texto de constructor. Luego se establece un valor para la variable "nombre" y finalmente, invoca un método denominado evaluar, que confirma los valores que se le estan pasando al constructor.

La salida resultante es a la altura de las expectativas.
¿Cómo se siente? ¿Es así como le gustaría que el sistema de plantillas trabajé? Vamos a proceder y ver cómo podemos hacer que el compilador potencie el código.

Haciendo una compilación con éxito

El compilador está dispuesto a recordarnos que, a pesar de nuestras intensiones, la plantilla de clase no existe. Se debe destacar que los métodos establecidos y evaluar no existen asi que tendremos que añadirlos. Terminamos con el esqueleto de una clase, en el listado 2.4.
Finalmente compilamos el código. Que viene luego? , ejecutamos el test.


Ejecutamos el test

Cuando ejecutamos nuestro código recién escrito, se produce un error- no es de extrañarnos - porque no hemos añadido aún los métodos.

Ejecutamos la prueba para obtener la salida como se muestra en la figura 2.2, obteniendo un mull cuando se esperaba una cadena "Hola, lector"

Estamos en la fase roja del ciclo TDD, lo que significa que hemos escrito y ejecutado una prueba que está fallando, y nuestro IDE indica una barra roja en su compilación. Ya hemos escrito una prueba y tenemos un esqueleto del código de producción que pone a prueba nuestra prueba. Por ahora, todo lo que queda es implementar la plantilla de clase para que al compilarlo veamos una barra verde en nuestro IDE.

1.4 Pensando en la construcción correcta: pruebas de aceptación TDD

El testing siempre ha sido una parte integral del desarrollo de software. Sin embargo, el camino del testing ha sido llevado ha cambios significativos a lo largo de década. Como programadores, hemos tenido siempre interés en conocer qué nuestro software trabaja, antes de que sea pasado a los usuarios . Lo que significa que obtenemos conocimiento, sin embargo, ha evolucionado obteniendo software ágil de desarrollo como es la Programación Extrema.

Adicionalmente, el rol del test de ellos mismos, ha modificado entre otras áreas del desarrollo de software, planificando la verificación para confirmar para especificar. En efecto, la solución para el segundo tiempo de nuestro problema de código es omitirlos, para encontrarse con la actual necesidad es permitir test manejados sobre el desarrollo a nivle de la construcción y funcionalmente en la construcción del sistema. Es decir, practicamente test de aceptación sobre el desarrollo. En conclusión, "Hacemos sólo pruebas de ejecución en una parte del sistema cuando los test son llamados".

En esecencia, significa que los test no son llamados meramente una verificación de instrumentos, si no como una parte integral de requerimientos y especificacion así comop también un medio para colaborar con el negocio.En esta sección , iremos introduciéndonos en más detalle sobre esos nuevos roles de los test, comenzando con examinar y nutrir la estrecha colaboración entre el desarrollo , tester , y negocio , y discutir el uso de los test como un lenguaje compartido facilitando la colaboración.

Antes de discutir los aspectos de la técnica de la colaboración orientada, debemos relacionar la relación entre los test de aceptación y TDD. Después de todo, sus nombres son apenas idénticos.

1.4.1 Cuál es su nombre?

El nombre "test de aceptación" implica que la aceptación de TDD es igualmente algo similar para "regular" TDD. El sufijo es obviamente procede de TDD, pero de donde viene el resto? Qué es test de aceptación? En conclusión , test de aceptación son indicadores de la completación de un requerimiento o aspecto. Todo test de aceptación para un requerimeinto o presentación pasada, permite saber lo que hace.

TDD de aceptación es una técnica , no es una combinación para especificar formas para expresar requerimientos. La misma idea puede ser aplicada para algunos efectos tanto como implementando casos de uso, historias , o otros medios equivalentes para documentar lo que tiene que hacer. Esto denota un valor, es decir, ese equipo usando historias para administrar sus requerimientos tienden a llamarlo "historias de test en ejecución de desarrollo" en cambio - cúal es un nombre diferente para alguna técnica. A pesar de eso otros prefieren llamarlo " test de ejecución de desarrollo de negocio", lo cual es apropiado considerando la naturalidad del test.

Nota: Sin embargo TDD y TDD de aceptación tiene mucho en común y ciertamente el hermano mayor tiene mucho que parender de su hermano menor, pero ambos TDD Y TDD de aceptación pueden ser adoptados en forma excluyentes. Los programadores que no tienen historias de usuarios a la vista que aún no pueden hacerlo para una funcionalidad determinada, todavía pueden adoptar TDD y cosechar sus beneficios tales como; equipos de prueben previamente antes de integrar funciones. Esta práctica producen una mejora más que el uso de cualquiera de ellos solos.

Independientemente del formato específico o herramienta que utilizamos para gestionar los requisitos, el principla objetivo de la Aceptación TDD es, apoyar la colaboración estrecha entre el cliente y el equpo de desarrollo. Vamos a ver como está basado en pruebas.

1.4.2 La estrecha colaboración


Estrecha colaboración es escencial para cualquier esfuerzo complejo que invlucre a personas y desarrollo de software con TDD de aceptación. En la práctica se requiere tener un equipo de proyecto integrado de desarrollo, en empresas, análisis, pruebas de equipos y departamento de control de calidad.

La idea fundamental es alcanzar el mejor nivel de productividad para todo el equipo, alimentando una respuesta rápida y eficaz cara a cara, con una buena comunicación, software de trabajo que impidan las pruebas planas, especificaciones e informes de incidencias entre los clientes, usuarios, analistas de negocios y desarrolladores. Con TDD de aceptación , somo capaces de colaborar efectivamente y reunir conocimientos , destrezas y habilidades necesarias para hacer un buen trabajo.

Veamos como la estrecha colaboración ayuda a liberar un producto correcto con la mejora de nuestras iteraciones reduciendo la probabilidad de incidencias.

Viendo concretamente el trabajo de software

Existen clientes despues de varios meses, demuestran no estar contentos o satisfechos con entregas de trabajo de contratistas.Informar al cliente con entregas continuas de funcionalidades, estamos asegurandonos de que, si hay algo incorrecto o no, lo sabremos de inmediato. Esta temprana retroalimentación reduce riesgos y costos. Además al no llevar un inventario, donde se detalle de las funcionalidades terminadas , estamos evitando mostrar el progreso del desarrollo, como por ejemplo "desarrollo es de 90% completo"

Creando confianza y confianza


Otro beneficio que se gana al realizar entregas tempranas de trabajo de software y con frecuencia es que estamos contruyendo confianza, tanto entre el equipo y el cliente como dentro del mismo equipo. Al mostrar a lo clientes (y a nosotros mismos) que podemos entregar iteraciones de versiones, estamos haciendo la vida mucho más fácil para todo nuestro equipo.

El cliente tiene el control

Hay una diferencia clave en el rol y poder entre los desarrollos incrementales y el desarrollo tradicional de casacada del cliente. Pues, con el desarrollo incremental el cliente elige y busca las características principales. Del mismo modo, elige las características que puede eliminar, no disponibles para ser implementadas y que estan dentro del proyecto asignado en tiempo o presupuesto.

Las decisiones de los clientes son, seguros, influenciado por el costo de las caracteríticas, que por las estimaciones de los desarrolladores- incluyendo el costo de las demoras, construcción, orden , etc.

La capacidad del cliente en tomar decisiones en que se gasta sus dinero y cambiar su forma de mirar a los proyectos de software. Por último, el cliente tiene el control. Hable sobre cómo motivar a los clientes¡¡


La evolución de un trabajo compartido

Al fomentar una estrecha colaboración entre los testeadores , desarrolladores y clientes, somos efectivos facilitadores a una situación donde la información necesaria se obtiene tan pronto como sea posible -en todas las direcciones. Además, esta exposición es continúa en el equipo aumentando la eficiencia en la comunicación como el conocimiento entre los desarrolladores generando un lenguaje compartido. El desarrrollo de software es un negocio de personas y no debemos descuidarnos en ello.

Vamos a ver la posibilidad de usar test de aceptación usando como fundamento un lenguaje compartido incluyendo a cliente y al equipo de desarrollo y tester.

1.4.3 Test como un lenguaje compartido

Uno de los mayores problemas en el desarrollo de software es no tener claridad de los requerimientos o necesidades del cliente. Esto deja de ser un juego de niños para expresar y comunicar los requisitos de tal forma que ninguna información pierda la transmisión de la idea original. Algunos dicen a lo lejos que es imposible realizarlo. Despues de todo , no podemos leer la mente de nuestros clientes.

Este problema es evidente cuando usamos un medio de comunicación es por medio de una documentación escrita- por ejemplo, especificaciones de requerimientos- lo cual es lejos un medio perfecto para la transferencia y comprensión de la información. Si pudieramos ser capáz de trasnformar los requisitos en pruebas ejecutables y que verificaran si el sistema se ajusta a las aspectos y condiciones particulares, habría menos problemas con las ambiguedades y el espacio entre la interpretación y los desarrolladores. Esta es la premisa perfecta de los test como especificaciónes.

Test de Pruebas como especificaciones.

Los test como especificaicones provee una manera de de ver las pruebas como algo esencial que se derivan de los requisitos, por lo que en teoría, un sistema que pasa sus pruebas , se ajustan a la especificación.

De vez en cuando, obtenemos defectos a través de pruebas. Esto no es novedad para quienes hemos estado a lo menos en dos proyectos de software comercial. Esto se debe por no considerar todas las pruebas las pruebas necesarias. En parte , esto se debe a nuestra naturaleza humana y nuestra intuición engañosa, donde , sólo se resuleven algunas incidencia para ahorra tiempo.

Esto nos plantea la pregunta, ¿Estamos realmente usando los test como especificaciones , si los tests tienden a fugarse por otros caminos? Esto es realmente factible para el uso de los test como especificaciones, efectivamente redifiniendo el significado de los conceptos?. Usando test como especificaciones no es una bala de plata, pero tiene una serie de ventajas que valen la pena considerar.

  • Más rápido a través de la automatización.
  • Ejecución de pruebas más confiables.
  • Menos pasos.
En primer lugar, no se puede negar que al tener automatizadas las pruebas ejecutables, nos deshacemos de un montón de duro trabajo, acelerando las iteraciones enormemente, si lo comporamos si lo realizamos manualmente.En segundo lugar, evita la negligencia de pereza que poseemos los humanos. Finalmente , hacemos de los errores una traducción de los verdaderos requerimientos en la escritura con verdaderas prácticas.

Aún en la transformación de requerimientos en los test , existen la posibilidad de errar. pero, la transferencia de conocimientos y la interpretación humana implica la ejecución de los test con menos cambios en los lugares donde se ha diseño.

Ejemplo de especificación.


Uno de los beneficios más notables del uso de pruebas como especificaciones, es el impulso de desarrollar pruebas típicas que empleen especificaciones no abstrata en escritura, es decir, en vez del tradicional "el sistema deberá calcular el impuesto de...." como patrón de los documentos de requerimientos, sino especificaciones como por ejemplo "para una suscrpción de 20 dólares con un tipo impositivo del 10%, el sistema carga un total de 22 dólares de la cuenta del usuario"

Este simple requerimientos, se diferencia entre el tradicional "el sistema debera..." y el ejemplo basado en versiones no tan significativas- después de todo , sabemos como calcular el impuesto como caso trivial, Sin embargo, los requerimientos para cumplir con el trabajo no suelen ser tan triviales, y el riesgo de mantenerlos es mucho más alto. Por ejemplo, la aplicación de impuesto múltiples para una operación determinada, puede ser que necesite emplear diferenctes reglas en diferentes lugares, que pueden ser aclarados a través de ejemplos concretos.

La especificaciones es un paso natural de nuestra intuición y hace más fácil relacionar los requerimientos para el mundo concreto en nuestro software. Las especificaciones también se pueden ver en TDD. Considerando que las pruebas de aceptación especifican el comportamiento deseado del sistema, los ejemplos y el comportamiento deseado especificado con las pruebas unitarias especifican acerca de la apliclación deseada y no de la funionalidad entregada.

Mayor calidad por dentro y fuera, mejor confianza en nuestro trabajo, y al cliente queda complacido frente a un software ajustado a sus necesidades. Después de todo, todo es posible. Luego haremos nuestra propia caminata o conversación pero, primero hablaremos de las herramientas a nuestra disposición.

1.5 Herramientas para el desarrollo de ejecución de test


Las herramientas son importantes. Sin herramientas como compliladores, editores, sistemas de explotación , desarrollo de software sería difícil comparádolo donde han llegado décadas y décadas de avances técnicos. Ahora vamos a tomar tres categorías fundamentales de herramientas y técnicas: un frameworks de testing unitarios, integración contínua con mecanismo de apoyo y, cobertura de código.

1.5.1.- Pruebas unitarias con xUnit


Hace años, Kent Beck creó un framework de pruebas unitarias para SmallTalk llamado SUnit (http://sunit.sf.net). Este framework ha sido la luz para circular dentro de la comunidad de desarrollo de software.Esta misma herramienta basada en SUnit - es llamada también JUnit, disponible en http:/www.junit.org/ . La familia de los frameworks de pruebas unitarias basados en los patrones encontrados en SUnit y JUnit es similar a xUnit. ¿Qué hacen exactamente?

¿Qué hace exactamente el framework de pruebas unitarias en el contexto de xUnit?, Significa que la librería ofrece apoyo para escribir código de pruebas unitarias, ejecutarlas sobre los resultados de prueba. En el caso de Junit, proporciona un conjunto de clases e interfaces para tareas comunes aserciones , y así sucesivamente. Para ejecutar los JUnit escritos en Junit, el proyectos provee de diferentes test runners- son clases que saben como coleccionar un ser de pruebas unitarias , los ejecuta , colecciona los resultados , y muestra el desarrollo gráficamente o resumen de resultado.

En este libro veremos JUnit y Java. De hecho usaremos varias ampliaciones de JUnit a medida que avanzamos en una prueba de manejo diferentes tipos de componentes. Si usted no está familiarizado con JUnit, por favor, refiérase a los apéndices de una introducción a esta pequeña y maravillosa herramienta. No demasiados inmersos en los detalles de JUnit, tenemos un par de categorías adicionales de las herramientas para ejecutar las pruebas de aceptación de TDD.

1.5.2 Framework para test de TDD de aceptación.

Aunque los frameworks de los escenarios de test unitarios, se ha desarrollado bajo el concepto de xUnit, no es tan homogéneo en el mundo de las pruebas de aceptación. La principal razón de esta diferencia es la idea de una prueba de manejo en el nivel funcional ya que es relativamente nuevo, y la ejecución iterativamente de las pruebas con herramientas de automatización no funcionan bien cuando no hay nada para grabar.

Otra cosa al pensar sobre la fragmentación del negocios es, el factor de dos sistemas rara vez tienen la mismas interfaces exacta. La excepción a la regla es la aplicación web, la cual puede ser accesadas con tecnologías estándar, como el protocolo HTTP y el lenguaje de tag HTML. Lo que es más importante que las tecnologías involucradas, son las herramientas destinadas a apoyar nuestro ineterés primordial con TDD de aceptación- cierra el negocio de colaboración.

Existen herramientas como FIT y FITnesse que son orientadas a tablas visuales que colaboran con los desarrolladores, testeadores y analistas de negocio no técnicos. Fit usa un formato tabular con una familia de herramientas , que permiten escribir pruebas ejecutables que representan pruebas como declaraciones. Una de las herramientas más conocidas de esta categoría es EXACTOR. A veces es sufiente para los fines de un proyecto dado utilizar un medio más técnicos, como un lenguaje de secuencias de comandos para describir pruebas. Es un framework para pruebas de aceptación , de fácil acceso, otra opción es manejar un framework de propia cosecha.

Vamos a ver más de cerca algunas de estas herramientas en la parte 3 al explorar la aceptación basado en pruebas en un mayor desarrollo. Por ahora , pasaremos a la siguiente herramienta relacionada que deben cubrir a los continuos servidores.

1.5.3.- Integración contínua y constructores.

Trabajar en un equipo que está en constante cambio en el código aqui y allá, crea una presión en los desarrolladores para integrar sus cambios significativos. algunos utilizados en entornos tradicionales. Los equipos que utilizan TDD emplean la por propiedad el código colectivo, lo que significa que todos estan autorizado para cambiar cualquier código base.

En la práctica, esto significa que mientras el equipo está refactorizando como parte de su ciclo de pruebas, habrá un flujo constante de pequeños cambios en el repositorio de código fuente. Con esto en mente, esperando a que dos días antes se chequen tus cambios e igualmente los requerimientos manualmente- esta es una actividad que no gusta mucho.

Todo esto nos lleva a adoptar un proceso sincronizado en nuestros cambios en el repositorio de fuentes con más frecuencia que antes. La alta frecuencia de integración
de los desarrollos, da un espacio a los desarrolladores en un repositorio centralizado, donde no solo cabe la integración de la fuente en la compilación sino también en la verificación de la fuente integrada mediante la ejecución de pruebas automatizadas.

Ventajas y Desventajas

Un patrón común con los equipos de aplicación contínua es ejecutar un subconjunto de todas las pruebas antes de comprobar en sus cambios y delegar en funcionamiento de la suite de pruebas (incluyendo la unidad, integración y pruebas funcionales) a un servidor dedicado a contruir, también conocido como una acumulación contínua con el servidor. En la figura 1.12 muestra una configuración básica con un servidor de integración contínua de votación para los cambios de el repositorios de código fuente.


En escencia , esta es una práctica que muchos equipos deciden hacer. Por un lado hacer correr las suit de test demora un varios minutos que esperar la barra verde, es decir que los test se hayan ejecutados sin problemas.

En el caso que los cambios puedan romper alguna prueba del desarrollador, no hay que ejecutarlos sin antes notificarlos al resto del equipo y verificar la base de código donde fué roto los cambios recientes.

Construir servidores con servicios varios

Afortunadamente usted no necesita escribir sus propias herramientas para ejecutar un servicios para lo construído, debido que existen productos de código abierto, así como existen productos comerciales que ofrecen funcionalidades necesarias. Algunos de los populares incluyen Cruise- Control (http://cruisecontrol.sf.net), hormiguero (htpp:/www.urbancode.com), Continuum (htpp://maven.apache.apache.org/continuum) y Bambú (htpp://www.atlassian.com/software/bamboo/)., y otros que estan apareciendo en el tiempo.

Si usted está interesado en aprender más sobre integración contínua y sus herramientas asociadas, consulte el artículo de Martin Fowler "Continua Integración" o James Costa ha hecho una gran escritura de la diferencia entre hacer la integración contínua y el uso de servidores de integración continúa.

1.5.4 Código de cobertura

Muchos desarrolladores están familiarizados con herramientas de análisis de código estático.Los desarrolladores en particular, podrían tener experiencia en ejecutar la herramienta PMD (http:/pmd.sf.net) para detectar anomalías en relación con el uso ilegal de determinadas construcciones o para calcular las mediciones de la complejidad. La mayor atención a las pruebas automatizadas y especialemnete , las pruebas unitarias , también se creado una serie de herramientas para medir la cobertura del código. en resúmen . la cobertura del código es una medida de cúanto findo ejercen nuestras pruebas automatizadas en el código de producción y sus declaraciones de código de fuente, ramas y expresiones.

El principal beneficio es la incorporación de medidas de cobertura de código basado enla constante prueba de nuestro software. Esto es especialmente útil cuando un equipo está empezando aescribir las pruebas unitarias o la adopción de TDD, porque ayuda a la búsqueda de ámbitos de la base de código.

¿Qué grado de cobertura debo apuntar?

Cuando nos planteamos el tema de cobertura , nos cuestionamos a qué altura debemos poner el listón de cobertura, si es de un 100%, 90% o un 80%?.
La respuesta es depende , de las tecnologías específicas , idiomas, herramientas en uso y frecuencia. Para Java y proyectos J2ee es una cobertura promedio de 85%.