Diferencia entre revisiones de «Concordion»
(→Comandos de Concordion) |
|||
(No se muestran 54 ediciones intermedias de 3 usuarios) | |||
Línea 1: | Línea 1: | ||
− | Concordion es un framework [[Java]] de [[Software Libre]] que permite convertir especificaciones en texto común sobre requerimientos en pruebas automatizadas. | + | [[Concordion]] es un framework [[Java]] de [[Software Libre]] que permite convertir especificaciones en texto común sobre requerimientos en pruebas automatizadas. |
==Las especificaciones== | ==Las especificaciones== | ||
− | En Concordion, las especificaciones(o pruebas de aceptación) se escriben normalmente en archivos HTML, usando tablas y todos los elementos comunes para darle formato. De esta manera se logran especificaciones muy fáciles de leer y que todos pueden comprender (desde analistas de negocio hasta desarrolladores). | + | En [[Concordion]], las especificaciones (o pruebas de aceptación) se escriben normalmente en archivos HTML, usando tablas y todos los elementos comunes para darle formato. De esta manera se logran especificaciones muy fáciles de leer y que todos pueden comprender (desde analistas de negocio hasta desarrolladores). |
==Las pruebas== | ==Las pruebas== | ||
Línea 8: | Línea 8: | ||
A partir del requerimiento en HTML se realizan asociaciones entre el texto y las pruebas (instrumentación del HTML), extrayendo la información valiosa para la prueba automatizada. | A partir del requerimiento en HTML se realizan asociaciones entre el texto y las pruebas (instrumentación del HTML), extrayendo la información valiosa para la prueba automatizada. | ||
− | Las pruebas en Concordion son pruebas [[JUnit]]. | + | Las pruebas en [[Concordion]] son pruebas [[JUnit]]. |
==Ejemplo de Uso== | ==Ejemplo de Uso== | ||
+ | Vamos a trabajar con el paradigma de [http://www.dosideas.com/java/353-que-es-bdd.html BDD] y como hacerlo con [[Concordion]]. Hagamoslo en 2 etapas: | ||
+ | * '''Primero: Especificación''' | ||
+ | * '''Luego: Prueba''' | ||
− | Tomamos una pequeña aplicación de servicios que | + | Tomamos como proyecto el desarrollo de una pequeña aplicación de servicios que se pide en el [http://www.dosideas.com/cursos/course/view.php?id=4 Curso de Introducción al desarrollo Java EE]. Donde necesitamos hacer un servicio que, dado un id de provincia, devuelva la provincia en cuestión. El contrato de negocio dice que: |
− | |||
* si se invoca con un id existente, se devuelve la provincia correspondiente | * si se invoca con un id existente, se devuelve la provincia correspondiente | ||
* si se invoca con un id inexistente, se devuelve null | * si se invoca con un id inexistente, se devuelve null | ||
* si se invoca con un null, se tira una java.lang.IllegalArgumentException | * si se invoca con un null, se tira una java.lang.IllegalArgumentException | ||
− | + | ===Especificación de una historia=== | |
+ | Veamos algunos pasos claves para empezar la especificación: | ||
− | + | 1. Elegir una de las historias a ser implementada por el proyecto. | |
− | + | ||
− | + | Si trabajamos con [[Scrum]], trabajamos con historias, y supongamos que en esta iteración nos toca trabajar con la historia "Consulta de Provincia". Para esto tenemos que tener en claro el contrato de negocio que acompaña a esta historia. | |
− | + | ||
+ | 2. Escribir la página con las especificaciones de la historia. | ||
+ | |||
+ | La página tiene que ser un resumen del criterio de aceptación acordado por el grupo. Es el acuerdo al que se llega entre desarrolladores, tester, dueño del producto y analista de negocio. | ||
+ | |||
+ | Podríamos dividir la página en sesiones: "Automatizado", "Manual" y "Fuera de Alcance". Idealmente, la prueba de aceptación debiera estar totalmente automatizada, pero en ocasiones se necesitan pruebas manuales, por ejemplo, cuando la prueba no es fácil de automatizar. | ||
+ | |||
+ | 3. Escribir el detalle del criterio de aceptación. | ||
+ | |||
+ | Esto se escribe y acuerda como equipo antes de comenzar a escribir líneas de código. | ||
+ | |||
+ | Si la página HTML, usa el título Automatizado. Lo que sigue al título es un link a cada prueba de aceptación. Los tests se organizarán de forma que sean facilmente navegable. | ||
+ | |||
+ | Cada página necesita un encabezado conciso, una descripción y uno o más ejemplos. Agregando a la pagina HTML, una sesión de "Escenarios Alternativos", podemos incorporar un link por cada cuestión a la funcionalidad. Y ese link es a otra especificación sencilla. | ||
+ | |||
+ | [[Imagen:EjemploHTMLConcordionPre.jpg]] | ||
+ | |||
+ | En términos de HTML: | ||
+ | |||
+ | <code html4strict> | ||
+ | <html xmlns:concordion="http://www.concordion.org/2007/concordion"> | ||
+ | <head> | ||
+ | <link href="../concordion.css" rel="stylesheet" type="text/css" /> | ||
+ | </head> | ||
+ | <body> | ||
+ | <h1>Consulta de Provincia</h1> | ||
+ | <p> | ||
+ | Queremos obtener el nombre una provincia en base a una | ||
+ | identificacion. | ||
+ | </p> | ||
+ | <p> | ||
+ | El sistema devuelve el nombre de la provincia. | ||
+ | </p> | ||
+ | <div class="provincia"> | ||
+ | <h3>Ejemplo</h3> | ||
+ | <table> | ||
+ | <tr> | ||
+ | <th>id</th> | ||
+ | <th>Nombre Provincia</th> | ||
+ | </tr> | ||
+ | <tr> | ||
+ | <td>1</td> | ||
+ | <td>Buenos Aires</td> | ||
+ | </tr> | ||
+ | </table> | ||
+ | <h3>Escenarios Alternativos</h3> | ||
+ | <h5> | ||
+ | <a href="./ProvinciaInexistente.html"> | ||
+ | Que pasa si el id de provincia pasado no existe? | ||
+ | </a> | ||
+ | </h5> | ||
+ | <h5> | ||
+ | <a href="./IdentificacionNula.html"> | ||
+ | Que pasa si no pasamos el id de provincia? | ||
+ | </a> | ||
+ | </h5> | ||
+ | </div> | ||
+ | </body> | ||
+ | </html> | ||
+ | </code> | ||
+ | |||
+ | 4. Ahora, todos sabemos que significa que la historia está terminada. | ||
+ | |||
+ | Lleva algún tiempo escribir el criterio de aceptación, quizás 2 o 3 horas para una historia de 5 dias. Pero esto se gana en términos de enfoque, cobertura de los test, y el alcance de la funcionalidad. | ||
+ | |||
+ | 5. Una vez completa la especificación, estamos listos para desarrollar el cumplimiento de la especificación. | ||
+ | |||
+ | ===Prueba de una historia=== | ||
+ | |||
+ | 1. Incorporar los jars que necesitamos en el proyecto para hacer BDD: | ||
+ | |||
+ | *concordion-1.3.1-RC4.jar | ||
+ | *ognl-2.6.9.jar | ||
+ | *xom-1.1.jar | ||
+ | *junit-4.5.jar | ||
+ | |||
+ | 2. Definir un módulo nuevo para hacer BDD en el proyecto. | ||
+ | |||
+ | Necesitamos un nuevo módulo de especificaciones. Y paquetizamos el módulo por funcionalidad/historias. | ||
+ | |||
+ | [[Imagen:EstructuraProyectoConConcordion.jpg]] | ||
+ | 3. Escribir el test con JUnit. | ||
− | == Ver también == | + | Para el ejemplo que venimos viendo necesitamos la clase java ConsultaDeProvinciaTest.java. |
+ | |||
+ | <code java> | ||
+ | package com.dosideas.provincia; | ||
+ | |||
+ | import com.dosideas.business.ejb.provincia.ProvinciaSessionRemote; | ||
+ | import com.dosideas.domain.Provincia; | ||
+ | import javax.naming.InitialContext; | ||
+ | import javax.naming.NamingException; | ||
+ | import javax.rmi.PortableRemoteObject; | ||
+ | import org.concordion.integration.junit3.ConcordionTestCase; | ||
+ | import org.junit.Before; | ||
+ | import org.junit.Test; | ||
+ | |||
+ | public class ConsultaDeProvinciaTest extends ConcordionTestCase { | ||
+ | private ProvinciaSessionRemote instance; | ||
+ | @Before | ||
+ | public void setUp() throws NamingException { | ||
+ | InitialContext initialContext = new InitialContext(); | ||
+ | Object paisObject = initialContext.lookup("ejb/ProvinciaSessionBean"); | ||
+ | instance = (ProvinciaSessionRemote) PortableRemoteObject.narrow(paisObject, | ||
+ | ProvinciaSessionRemote.class); | ||
+ | } | ||
+ | @Test | ||
+ | public String obtenerProvincia(Long id) { | ||
+ | Provincia provincia = instance.buscarProvinciaPorId(id); | ||
+ | return provincia.getNombre(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | 4. Asociar el test a la especificación en HTML. | ||
+ | |||
+ | <code html4strict> | ||
+ | <table concordion:execute="#nombreProvincia = obtenerProvincia(#id)"> | ||
+ | <tr> | ||
+ | <th concordion:set="#id">id</th> | ||
+ | <th concordion:assertEquals="#nombreProvincia">Nombre Provincia</th> | ||
+ | </tr> | ||
+ | <tr> | ||
+ | <td>1</td> | ||
+ | <td>Buenos Aires</td> | ||
+ | </tr> | ||
+ | </table> | ||
+ | </code> | ||
+ | |||
+ | 5. Ahora, todos podemos demostrar el comportamiento de la historia. | ||
+ | |||
+ | Ejecutando ConsultaDeProvinciaTest.java. El framework de [[Concordion]] nos deja los resultados en el archivo html, en un directorio de salida. | ||
+ | |||
+ | [[Imagen:EjemploHTMLConcordionPost.jpg]] | ||
+ | |||
+ | El verde dice que se cumple con el comportamiento especificado. En rojo, estaríamos en problemas. | ||
+ | |||
+ | ==Gráficamente== | ||
+ | |||
+ | [[Imagen:StoryDeliveryLifecycle.jpg]] | ||
+ | |||
+ | ==Comandos de Concordion== | ||
+ | * '''Set''' | ||
+ | El comando set es necesario cuando tengamos que setear el valor de una variable que luego se usará como parámetro de una instrucción, o simplemente para ser mostrado dentro del html en más de un lugar. | ||
+ | |||
+ | Ejemplo de uso: | ||
+ | |||
+ | <code html4strict> | ||
+ | El usuario <span concordion:set="#usuario">Pepe</span> | ||
+ | </code> | ||
+ | |||
+ | * '''Execute''' | ||
+ | El comando execute tiene tres usos principales: | ||
+ | |||
+ | 1. Ejecutar una instrucción cuyo resultado es "void". | ||
+ | Como regla general, los métodos que devuelven void llamados desde un execute deberían comenzar con la palabra set o setUp. P.ej. setUpUser(#username). | ||
+ | 2. Ejecutar una instrucción cuyo resultado es un objeto. | ||
+ | Esto permite comprobar varias propiedades de dicho objeto. | ||
+ | 3. Manejar frases con estructuras poco habituales. | ||
+ | |||
+ | Ejemplo de uso: | ||
+ | |||
+ | <code html4strict> | ||
+ | <span concordion:execute=setUser(#usuario)/> | ||
+ | </code> | ||
+ | |||
+ | * '''AssertEquals''' | ||
+ | El comando assertEquals permite que si el test JUnit ha ejecutado correctamente entonces se muestre una barra en verde sobre la especificación que espera ese comportamiento. | ||
+ | |||
+ | Ejemplo de uso: | ||
+ | |||
+ | <code html4strict> | ||
+ | <p concordion:assertEquals="getSaludo()">Hola Mundo!</p> | ||
+ | </code> | ||
+ | |||
+ | Nota: Esperamos que getSaludo retorne "Hola Mundo!" | ||
+ | |||
+ | * '''AssertTrue''' | ||
+ | El comando assertTrue permite aseverar que el test JUnit retorna el valor que especificamos en el html, entonces se muestra una barra en verde. | ||
+ | |||
+ | Ejemplo de uso: | ||
+ | |||
+ | <code html4strict> | ||
+ | <p concordion:assertTrue="getSaludo()">Hola Mundo!</p> | ||
+ | </code> | ||
+ | |||
+ | Nota: Esperamos que getSaludo retorne "Hola Mundo!" | ||
+ | |||
+ | * '''AssertFalse''' | ||
+ | El comando assertFalse permite aseverar que el test JUnit no retorna el valor que especificamos en el html, entonces se muestra una barra en verde. | ||
+ | |||
+ | Ejemplo de uso: | ||
+ | |||
+ | <code html4strict> | ||
+ | <p concordion:assertFalse="getSaludo()">Hola!</p> | ||
+ | </code> | ||
+ | |||
+ | Nota: Esperamos que getSaludo retorne "Hola Mundo!" | ||
+ | |||
+ | * '''Echo''' | ||
+ | El comando echo permite mostrar el valor de una variable del html. | ||
+ | |||
+ | Ejemplo de uso: | ||
+ | |||
+ | <code html4strict> | ||
+ | <span concordion:echo="#miVariable"></span> | ||
+ | </code> | ||
+ | |||
+ | ==Fuente== | ||
+ | Esta página está basada en la [http://www.concordion.org/ Web oficial de Concordion]. | ||
+ | |||
+ | ==Ver también== | ||
* [[Herramientas Para Pruebas De Aceptacion]] | * [[Herramientas Para Pruebas De Aceptacion]] | ||
− | |||
* [http://www.concordion.org/Tutorial_es.html Tutorial en Español] | * [http://www.concordion.org/Tutorial_es.html Tutorial en Español] | ||
* [http://code.google.com/p/concordion/ Código abierto en GoogleCode] | * [http://code.google.com/p/concordion/ Código abierto en GoogleCode] | ||
* [http://jmbeas.blogspot.com/2008/12/editor-para-concordion.html Plugin Eclipse] | * [http://jmbeas.blogspot.com/2008/12/editor-para-concordion.html Plugin Eclipse] | ||
+ | * [[Concordion Con Spring]] | ||
+ | * [[Indice en Concordion con Junit 4.4]] | ||
+ | |||
+ | [[Category:Java]] | ||
+ | [[Category:BDD]] |
Revisión actual del 16:40 17 mar 2010
Concordion es un framework Java de Software Libre que permite convertir especificaciones en texto común sobre requerimientos en pruebas automatizadas.
Contenido
Las especificaciones
En Concordion, las especificaciones (o pruebas de aceptación) se escriben normalmente en archivos HTML, usando tablas y todos los elementos comunes para darle formato. De esta manera se logran especificaciones muy fáciles de leer y que todos pueden comprender (desde analistas de negocio hasta desarrolladores).
Las pruebas
A partir del requerimiento en HTML se realizan asociaciones entre el texto y las pruebas (instrumentación del HTML), extrayendo la información valiosa para la prueba automatizada.
Las pruebas en Concordion son pruebas JUnit.
Ejemplo de Uso
Vamos a trabajar con el paradigma de BDD y como hacerlo con Concordion. Hagamoslo en 2 etapas:
- Primero: Especificación
- Luego: Prueba
Tomamos como proyecto el desarrollo de una pequeña aplicación de servicios que se pide en el Curso de Introducción al desarrollo Java EE. Donde necesitamos hacer un servicio que, dado un id de provincia, devuelva la provincia en cuestión. El contrato de negocio dice que:
* si se invoca con un id existente, se devuelve la provincia correspondiente * si se invoca con un id inexistente, se devuelve null * si se invoca con un null, se tira una java.lang.IllegalArgumentException
Especificación de una historia
Veamos algunos pasos claves para empezar la especificación:
1. Elegir una de las historias a ser implementada por el proyecto.
Si trabajamos con Scrum, trabajamos con historias, y supongamos que en esta iteración nos toca trabajar con la historia "Consulta de Provincia". Para esto tenemos que tener en claro el contrato de negocio que acompaña a esta historia.
2. Escribir la página con las especificaciones de la historia.
La página tiene que ser un resumen del criterio de aceptación acordado por el grupo. Es el acuerdo al que se llega entre desarrolladores, tester, dueño del producto y analista de negocio.
Podríamos dividir la página en sesiones: "Automatizado", "Manual" y "Fuera de Alcance". Idealmente, la prueba de aceptación debiera estar totalmente automatizada, pero en ocasiones se necesitan pruebas manuales, por ejemplo, cuando la prueba no es fácil de automatizar.
3. Escribir el detalle del criterio de aceptación.
Esto se escribe y acuerda como equipo antes de comenzar a escribir líneas de código.
Si la página HTML, usa el título Automatizado. Lo que sigue al título es un link a cada prueba de aceptación. Los tests se organizarán de forma que sean facilmente navegable.
Cada página necesita un encabezado conciso, una descripción y uno o más ejemplos. Agregando a la pagina HTML, una sesión de "Escenarios Alternativos", podemos incorporar un link por cada cuestión a la funcionalidad. Y ese link es a otra especificación sencilla.
En términos de HTML:
<html xmlns:concordion="http://www.concordion.org/2007/concordion">
<head> <link href="../concordion.css" rel="stylesheet" type="text/css" /> </head> <body>
Consulta de Provincia
Queremos obtener el nombre una provincia en base a una identificacion.
El sistema devuelve el nombre de la provincia.
Ejemplo
id | Nombre Provincia |
---|---|
1 | Buenos Aires |
Escenarios Alternativos
<a href="./ProvinciaInexistente.html"> Que pasa si el id de provincia pasado no existe? </a>
<a href="./IdentificacionNula.html"> Que pasa si no pasamos el id de provincia? </a>
</body>
</html>
4. Ahora, todos sabemos que significa que la historia está terminada.
Lleva algún tiempo escribir el criterio de aceptación, quizás 2 o 3 horas para una historia de 5 dias. Pero esto se gana en términos de enfoque, cobertura de los test, y el alcance de la funcionalidad.
5. Una vez completa la especificación, estamos listos para desarrollar el cumplimiento de la especificación.
Prueba de una historia
1. Incorporar los jars que necesitamos en el proyecto para hacer BDD:
- concordion-1.3.1-RC4.jar
- ognl-2.6.9.jar
- xom-1.1.jar
- junit-4.5.jar
2. Definir un módulo nuevo para hacer BDD en el proyecto.
Necesitamos un nuevo módulo de especificaciones. Y paquetizamos el módulo por funcionalidad/historias.
3. Escribir el test con JUnit.
Para el ejemplo que venimos viendo necesitamos la clase java ConsultaDeProvinciaTest.java.
package com.dosideas.provincia;
import com.dosideas.business.ejb.provincia.ProvinciaSessionRemote; import com.dosideas.domain.Provincia; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import org.concordion.integration.junit3.ConcordionTestCase; import org.junit.Before; import org.junit.Test;
public class ConsultaDeProvinciaTest extends ConcordionTestCase {
private ProvinciaSessionRemote instance; @Before public void setUp() throws NamingException { InitialContext initialContext = new InitialContext(); Object paisObject = initialContext.lookup("ejb/ProvinciaSessionBean"); instance = (ProvinciaSessionRemote) PortableRemoteObject.narrow(paisObject, ProvinciaSessionRemote.class); } @Test public String obtenerProvincia(Long id) { Provincia provincia = instance.buscarProvinciaPorId(id); return provincia.getNombre(); }
}
4. Asociar el test a la especificación en HTML.
id | Nombre Provincia |
---|---|
1 | Buenos Aires |
5. Ahora, todos podemos demostrar el comportamiento de la historia.
Ejecutando ConsultaDeProvinciaTest.java. El framework de Concordion nos deja los resultados en el archivo html, en un directorio de salida.
El verde dice que se cumple con el comportamiento especificado. En rojo, estaríamos en problemas.
Gráficamente
Comandos de Concordion
- Set
El comando set es necesario cuando tengamos que setear el valor de una variable que luego se usará como parámetro de una instrucción, o simplemente para ser mostrado dentro del html en más de un lugar.
Ejemplo de uso:
El usuario Pepe
- Execute
El comando execute tiene tres usos principales:
1. Ejecutar una instrucción cuyo resultado es "void". Como regla general, los métodos que devuelven void llamados desde un execute deberían comenzar con la palabra set o setUp. P.ej. setUpUser(#username). 2. Ejecutar una instrucción cuyo resultado es un objeto. Esto permite comprobar varias propiedades de dicho objeto. 3. Manejar frases con estructuras poco habituales.
Ejemplo de uso:
<span concordion:execute=setUser(#usuario)/>
- AssertEquals
El comando assertEquals permite que si el test JUnit ha ejecutado correctamente entonces se muestre una barra en verde sobre la especificación que espera ese comportamiento.
Ejemplo de uso:
Hola Mundo!
Nota: Esperamos que getSaludo retorne "Hola Mundo!"
- AssertTrue
El comando assertTrue permite aseverar que el test JUnit retorna el valor que especificamos en el html, entonces se muestra una barra en verde.
Ejemplo de uso:
Hola Mundo!
Nota: Esperamos que getSaludo retorne "Hola Mundo!"
- AssertFalse
El comando assertFalse permite aseverar que el test JUnit no retorna el valor que especificamos en el html, entonces se muestra una barra en verde.
Ejemplo de uso:
Hola!
Nota: Esperamos que getSaludo retorne "Hola Mundo!"
- Echo
El comando echo permite mostrar el valor de una variable del html.
Ejemplo de uso:
Fuente
Esta página está basada en la Web oficial de Concordion.