Apesar de mi mal comienzo con JBehave , debo decir que le voy cogiendo el tranquillo.
JBehave consiste en un sistema para hacer BDD en Java. En otras palabras: permite definir en un lenguaje no formal el comportamiento de la aplicación, utilizando expresiones regulares para transformarlo en un lenguaje formal.
Ejemplo
JBehave tiene cosas que no me gustan nada, pero también tiene otras que me gustan mucho. Veamos primero un ejemplito lo más pequeño que he sido capaz de hacerlo:
In order to show JBehave behaviour
As a newbie
I want to show this example
Given nothing special
When field operand1 contains 1And field operand2 contains 2And I press on "sum"
Then it returns 3
Como véis, parece una mini calculadora. Según la descripción, tendremos un campo “operand1” y otro “operand2”, que parece que pueden contener enteros. Además, tiene que haber un botón “sum” y, en alguna parte, mostrar un “3”. Admito todo tipo de críticas al respecto, pero recordad que se trata de algo sencillito.
Éste es el archivo de historia. Será necesario uno por cada historia (aunque hay maneras de necesitar menos). Lo que se hace es indicar la configuración necesaria para probar la historia de forma correcta. Como véis, lo único que hago es establecer la configuración por defecto, indicando que quiero las salidas de Consola, Html y estadísticas. Realmente nos bastaba con Consola, pero así véis más cosas.
Primera ejecución
Con esto ya podemos ejecutar el ejemplo. Evidentemente fallará, pero debe dar un resultado similar al siguiente:
Processing system properties {}
Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,storyTimeoutInSecs=300,threads=1]
(BeforeStories)
Using 1 threads
Using executor service java.util.concurrent.ThreadPoolExecutor@64883cRunning story org/magmax/jbehaveexample/my_example.story
(org/magmax/jbehaveexample/my_example.story)
Scenario: In order to show JBehave behaviour
As a newbie
I want to show this example
Given nothing special (PENDING)
When field operand1 contains 1 (PENDING)
And field operand2 contains 2 (PENDING)
And I press on "sum" (PENDING)
Then it returns 3 (PENDING)
@Given("nothing special")
@Pending
public void givenNothingSpecial(){
// PENDING
}
@When("field operand1 contains 1")
@Pending
public void whenFieldOperand1Contains1(){
// PENDING
}
@When("field operand2 contains 2")
@Pending
public void whenFieldOperand2Contains2(){
// PENDING
}
@When("I press on \"sum\"")
@Pending
public void whenIPressOnsum(){
// PENDING
}
@Then("it returns 3")
@Pending
public void thenItReturns3(){
// PENDING
}
(AfterStories)
Generating reports view to 'jbehaveexample/target/jbehave' using formats '[console, html, stats]' and view properties '{defaultFormats=stats, decorateNonHtml=true, viewDirectory=view, decorated=ftl/jbehave-report-decorated.ftl, reports=ftl/jbehave-reports-with-totals.ftl, maps=ftl/jbehave-maps.ftl, navigator=ftl/jbehave-navigator.ftl, views=ftl/jbehave-views.ftl, nonDecorated=ftl/jbehave-report-non-decorated.ftl}'
Reports view generated with 3 stories (of which 1 pending) containing 1 scenarios (of which 0 failed and 1 pending)
Lo más importante es fijarse en la parte que nos muestra el código java que
necesitamos para nuestros “steps”. Así que lo copiamos y lo pegamos en el
siguiente archivo (rellenándolo y quitando los @Pending):
packageorg.magmax.jbehaveexample;importorg.jbehave.core.annotations.Given;importorg.jbehave.core.annotations.Then;importorg.jbehave.core.annotations.When;import staticorg.junit.Assert.*;publicclassMyExampleSteps{intoperand1=0;intoperand2=0;intresult=0;@Given("nothing special")publicvoidgivenNothingSpecial(){}@When("field operand1 contains $value")publicvoidwhenFieldOperand1ContainsAValue(intvalue){operand1=value;}@When("field operand2 contains $value")publicvoidwhenFieldOperand2ContainsAValue(intvalue){operand2=value;}@When("I press on \"sum\"")publicvoidwhenIPressOnsum(){// Llamar a la calculadora realresult=operand1+operand2;}@Then("it returns $value")publicvoidthenItReturns3(intvalue){assertEquals(value,result);}}
Fijáos también que he realizado algunas modificaciones a la plantilla que me daba JBehave: he sustituido los valores por variables y he añadido parámetros en mis funciones. Las variables y los parámetros siempre coinciden en nombre, aunque las variables comienzan por el símbolo del dólar.
Fijáos también en el método whenIPressOnsum; aquí es donde iría la llamada a mi clase real, pero por abreviar, he puesto ahí mismo el código.
El caso es que esto no me funciona. No sé si es un problema de nomenclatura (asumo que sí), pero sé cómo arreglarlo: modificando nuestra clase que hereda de JUnitStory, de manera que sepa encontrar este archivo. Finalmente, quedaría así:
Como bien dije, hay cosas que me gustan mucho y otras que nada. Para empezar, está el objeto MostUsefulConfiguration. Se supone que es la configuración más útil, pero… ¿qué es lo más útil? Puede que sea la más común, pero lo cierto es que no incluye el formato “Console” y, como consecuencia, no imprime nada por pantalla. Eso me obliga a tener que sobreescribir el método de Configuración, como en el ejemplo.
Un acierto son las variables en las expresiones regulares, ya que JBehave es suficientemente listo como para resolverlas él solo. Quizá sea un poco peligroso en algún caso darle tanta inteligencia, pero en la mayoría de ellos viene muy bien.
Otra cosa que no me gusta es tener que indicarle el objeto que implementan los pasos a seguir. Debería encontrarse este objeto, basándose en la nomenclatura, de la misma manera que se ha encontrado el archivo .story.
Y otra cosa que no me gusta es tener que estar creando los archivos de historia, aunque siempre se puede crear uno genérico que permita encontrar todas las historias, aunque eso me ha dado no pocos dolores de cabeza.
Disculpas
En previsión de que me digáis que no tengo razón, abro ya este apartado. A penas he hecho 2 ejercicios con JBehave, así que es normal que me falten conocimientos y es posible que los problemas que he encontrado se puedan arreglar fácilmente. Me encantaría que me dijerais cómo :D
Más información
La mayor parte de la información la podéis obtener en la propia página de
JBehave reference, aunque el JavaDoc está a medias aún.