BDD, Cucumber y Gherkin. Desarrollo dirigido por comportamiento

BDD, Cucumber y Gherkin. Desarrollo dirigido por comportamiento
Sin comentarios Facebook Twitter Flipboard E-mail

BDD es uno de los términos de moda en el desarrollo de software en los últimos años. A pesar de ser un término muy utilizado, no todo el mundo sabe exactamente qué es eso de BDD, más allá del significado de esas siglas, Desarrollo Dirigido por Comportamiento (Behaviour Driver Development), ni cómo puede BDD ayudarnos en nuestro trabajo diario como desarrolladores.

BDD es una evolución de TDD (Test Driven Development o Desarrollo Dirigido por Pruebas). De hecho, el concepto de BDD fue inicialmente introducido por Dan North como respuesta a los problemas que surgían al enseñar TDD.

TDD está basado en 2 prácticas: Escribir las pruebas primero, y Refactorizar después:

TDD: En primer lugar, se escribe una prueba y se verifica que las pruebas fallan. A continuación, se implementa el código que hace que la prueba pase satisfactoriamente y seguidamente se refactoriza el código escrito

En BDD también vamos a escribir las pruebas antes de escribir el código fuente, pero en lugar de pruebas unitarias, lo que haremos será escribir pruebas que verifiquen que el comportamiento del código es correcto desde el punto de vista de negocio. Tras escribir las pruebas escribimos el código fuente de la funcionalidad que haga que estas pruebas pasen correctamente. Después refactorizamos el código fuente.

Partiremos de historias de usuario, siguiendo el modelo “Como [rol ] quiero [ característica ] para que [los beneficios]”. A partir de aquí, en lugar de describir en 'lenguaje natural' lo que tiene que hacer esa nueva funcionalidad, vamos a usar un lenguaje que nos va a permitir describir todas nuestras funcionalidades de una misma forma, un lenguaje específico para BDD, como Gherkin, del que hablaremos un poco más adelante.

Este lenguaje con el que vamos a describir las funcionalidades es lo que en DDD (Domain Driven Design o Diseño Guiado por el Dominio) llaman lenguaje ubicuo, es decir, un lenguaje semiformal que es compartido por todos los miembros de un equipo de desarrollo de software, tanto desarrolladores de software como personal no técnico. Este es uno de los aspectos claves: BDD facilita la comunicación entre todos los implicados en el desarrollo, sean técnicos o no.

BDD es un proceso de desarrollo de software que trata de combinar los aspectos puramente técnivos y los de negocio, de manera que tengamos un marco de trabajo, y un marco de pruebas, en el que los requisitos de negocio formen parte del proceso de desarrollo.

A la hora de definir cada funcionalidad, una opción es que esa definición venga por parte de negocio, quién posteriormente se la pasa a desarrollo (o testing), quienes escriben las pruebas. Es una opción, pero no es la única, y probablemente tampoco sea la mejor.

Otra opción es que sean los propios desarrolladores quienes escriban esta definición de las funcionalidades, a partir de la descripción a alto nivel de la funcionalidad que le ha dado la gente de negocio. Esto hace que los desarrolladores tengan que ver esa funcionalidad desde el punto de vista de negocio, y eso es positivo.

Una tercera posibilidad es que estas funcionalidades se escriban conjuntamente por negocio y desarrollo, por ejemplo durante la reunión del Sprint Planning. De esta forma pasaríamos de una lista de requisitos priorizada que el product owner presenta al equipo de desarrollo, a una lista de pruebas de comportamiento que pasan como tareas al Sprint Backlog.

Se trata de unir la especificación funcional con la documentación de pruebas, para ayudar a eliminar la distancia entre las personas de negocio y los desarrolladores.

Gherkin

Gherkin, es un lenguaje comprensible por humanos y por ordenadores, con el que vamos a describir las funcionalidades, definiendo el comportamiento del software, sin entrar en su implementación. Se trata de un lenguaje fácil de leer, fácil de entender y fácil de escribir. Es un lenguaje de los que Martin Fowler llama 'Business Readable DSL', es decir, 'Lenguaje Específico de Dominio legible por Negocio'.

Utilizar Gherkin nos va a permitir crear una documentación viva a la vez que automatizamos los tests, haciéndolo además con un lenguaje que puede entender negocio. Otro aspecto interesante es que se puede usar Gherkin en otros idiomas, no sólo en inglés. Actualmente Gherkin soporta más de 60 idiomas.

Lo bueno de Gherkin es que para empezar a hacer BDD sólo nos hace falta conocer 5 palabras, con las que construiremos sentencias con las que vamos a describir las funcionalidades:

  • Feature: Indica el nombre de la funcionalidad que vamos a probar. Debe ser un título claro y explícito. Incluímos aquí una descripción en forma de historia de usuario: “Como [rol ] quiero [ característica ] para que [los beneficios]”. Sobre esta descripción empezaremos a construir nuestros escenarios de prueba.
  • Scenario: Describe cada escenario que vamos a probar.
  • Given: Provee contexto para el escenario en que se va a ejecutar el test, tales como punto donde se ejecuta el test, o prerequisitos en los datos. Incluye los pasos necesarios para poner al sistema en el estado que se desea probar.
  • When: Especifica el conjunto de acciones que lanzan el test. La interacción del usuario que acciona la funcionalidad que deseamos testear.
  • Then: Especifica el resultado esperado en el test. Observamos los cambios en el sistema y vemos si son los deseados.

Lo normal es probar distintos escenarios para comprobar una determinada funcionalidad. De esta forma vamos a pasar de nuestras historias de usuario a pruebas de comportamiento automatizables. Para automatizar estas pruebas necesitamos apoyarnos en herramientas, como Cucumber, que entiende perfectamente el lenguaje Gherkin.

Cucumber

Cucumber es una de las herramientas que podemos utilizar para automatizar nuestras pruebas en BDD. Cucumber nos va permitir ejecutar descripciones funcionales en texto plano como pruebas de software automatizadas.

Cucumber fue creada en 2008 por Aslak Hellesoy y está escrito en Ruby, aunque tiene implementaciones para casi cualquier lenguaje de programación: JRuby (usando Cucumber-JVM), Java, Groovy, JavaScript, JavaScript (usando Cucumber-JVM y Rhino), Clojure, Gosu, Lua, .NET (usando SpecFlow), PHP (usando Behat), Jython, C++ o Tcl.

Otros frameworks BDD

Cucumer es probablemente la herramienta más conocida y más utilizada para automatizar pruebas en BDD, pero existen otros frameworks con los que poder hacer BDD para los lenguajes de programación más habituales:

Ejemplo de uso

Una de las formas más sencilla de instalar Cucumber para nuestras primeras pruebas es hacerlo con node. Para ello simplemente debemos ejecutar desde una ventana de línea de comandos:


npm install -g cucumber

Tras esto, si todo ha ido bien, tendremos cucumber instalado en nuestra máquina.

Los casos de tests se escriben en archivos con la extensión .feature, y dentro de cada uno de estos archivos hay uno o más escenarios de prueba. Primero vamos a crear una carpeta cucumber, dentro de esta una carpeta features, y dentro nuestro primer archivo .features.

Vamos a partir de una historia de usuario, con el esquema clásico: “Como [As a human] quiero [ search GenbetDev en Google] para que [find GenvetaDev website]”, para crear el caso de prueba que vamos a automatizar con Cucumber:


Feature: Buscar GenbetaDev en google
  As a human
  I want to search GenbetDev en Google
  So I can find GenvetaDev website
  Scenario: Search for Genbeta Dev
    Given I have visited Google
    When I search for "GenbetaDev"
    Then I see "Genbeta Dev"

Copiamos ese texto en nuestro archivo y lo llamamos 'my_feature.feature'. Ahora vamos a ejecutar nuestro test. Para ello, suponiendo que estemos en windows, desde una ventana de comandos ejecutamos:


cucumber-js features/my_feature.feature

En linux sería:


cucumber.js features/my_feature.feature

El resultado será el siguiente:

Cucumberfirsttest

Esto lo que nos indica es que debemos ahora implementar el código de pruebas que permita verificar ese test. Una posibilidad sería la siguiente:


module.exports = function() {

  this.Given(/^I have visited Google$/, function () {
    browser.url('http://google.com');
  });

  this.When(/^I search for "([^"]*)"$/, function (searchTerm) {
    browser.setValue('input[name="q"]', searchTerm);
    browser.keys(['Enter']);
  });

  this.Then(/^I see "([^"]*)"$/, function (link) {
    browser.waitForExist('a=' + link, 5000);
  });
}

Llegados a este punto, al contrario de lo que ocurría con Chimp.js, que se encargaba de instalar todo lo necesario para poder probar, con Cucumber tenemos muchas alternativas y somos nosotros los que debemos decantarnos por unas herramientas u otras como complemento, dependiendo también del lenguaje de programación que elijamos. Por ejemplo, para pruebas web, podemos apoyarnos en capybara, cucumber-mink, o en navegadores como zombie.js o phantom.js, junto con selenium webdriver.

Comentarios cerrados
Inicio