Los programadores de hoy en día utilizan cada vez más prácticas ágiles en su trabajo diario. Incluso los proyectos que siguen el ciclo de vida estándar de desarrollo de software pueden beneficiarse de su adaptación. Las pruebas automáticas y el TDD aportaron más confianza a nuestro trabajo, facilitaron la implementación de modificaciones en funciones existentes y a menudo nos llevaron a un mejor diseño del código. Pero ahora no basta. Tenemos que llevar los beneficios de las pruebas hasta el límite y BDD nos lo permite. Aporta un lenguaje omnipresente al proyecto, permite una mejor comunicación entre el cliente y los desarrolladores. Ofrece mucho a los directores y jefes de proyecto, pero también facilita mucho la vida de un desarrollador. Seguir los principios de BDD nos proporciona requisitos claros, las pruebas son más fáciles de entender y pueden servir como documentación. BDD cambia el enfoque de las pruebas y nos da la seguridad de que probamos lo que deberíamos probar: el comportamiento.
Si usas TDD, empezar con BDD será fácil - es básicamente un conjunto de buenas prácticas para ello. BDD tiene un conjunto de reglas simples, que dicen cómo escribir especificaciones y qué probar. Las especificaciones se dividen en tres partes: Dado (establecer las condiciones de la prueba), Cuando (invocar la acción sobre el sujeto) y Entonces (aserciones). Las pruebas deben tener nombres descriptivos y los marcos de pruebas existentes permiten utilizar métodos y aserciones similares al lenguaje natural, lo que combinado nos proporciona pruebas legibles tanto para usuarios técnicos como no técnicos. Unas buenas convenciones de nomenclatura resultan útiles durante las pruebas de regresión.
BDD también incluye una serie de directrices para los sujetos de las pruebas. A diferencia del TDD, se centra más en el comportamiento que en la implementación de las pruebas, lo que permite mejorar el diseño y ofrece más flexibilidad a la hora de introducir cambios. Las especificaciones deben ser como los requisitos escritos y ejecutables del cliente: las de alto nivel deben actuar como pruebas de aceptación. El objetivo es escribir las pruebas de forma que sólo sea necesario cambiarlas cuando cambien los requisitos. Utilizar BDD nos da la seguridad de que estamos probando lo que realmente hay que cubrir y es un enfoque más pragmático que TDD.
Si quieres ver BDD en acción, te recomendamos Ruby. Es un lenguaje potente y divertido de usar y cuenta con un excelente conjunto de herramientas BDD.
Pepino
Cucumber es el framework más popular para BDD en Ruby. Introduce un lenguaje especial, llamado Gherkin, en el que escribirás tus pruebas. En contraste con RSpec, las características descritas en Gherkin son texto plano, no códigoy, como tal, puede -y debe- ser comprendida por cualquiera, especialmente por el cliente.
Cucumber feature tiene este aspecto (ejemplo tomado de la wiki de Cucumber):
Característica: Un texto conciso pero descriptivo de lo que se desea
Descripción textual del valor empresarial de esta función.
Reglas empresariales que rigen el alcance de la función
Cualquier información adicional que facilite la comprensión de la función.
Escenario: Situación empresarial determinable
Dada una condición previa
Y alguna otra precondición
Cuando alguna acción del actor
Y alguna otra acción
Y otra acción más
Entonces se consigue algún resultado comprobable
Y también ocurre algo más que podemos comprobar
Escenario: Una situación diferente
...
Las características se describirán más adelante en detalle.
Uso de Cucumber en Ruby on Rails
Instalación
Primer paso para utilizar el pepino en su proyecto es instalarlo. Sólo tiene que añadir estas dos gemas a su Gemfile:
group :test do
gem 'cucumber-rails', :require => false
gem 'limpiador_base_de_datos'
end
Agrúpelos ejecutando instalación del paquetey generar scripts y directorios de Cucumber con el siguiente comando:
rails generate cucumber:install
Esto creará config/cucumber.yml, script/cucumber y características/ directorioque contendrá .característica así como definiciones de pasos y archivos de apoyo. Para ejecutar sus funciones, utilice un nuevo comando rake:
pepino de rastrillo
Características
Echemos un vistazo más de cerca a las funciones. Una funcionalidad es algo que tu aplicación tiene o hace - por ejemplo, envía periódicamente boletines o permite al usuario compartir sus fotos públicamente. Una función consta de varios escenarios, que describen cómo funciona en diferentes contextos.
Para demostrar el uso básico de Cucumber en Rails, escribiremos una funcionalidad desde cero. Esta funcionalidad de ejemplo será la primera que escribamos en la aplicación, que se mostrará en la segunda parte de este artículo. Esta aplicación permitirá al usuario crear artículos y tiendas (las tiendas venden artículos) y luego crear listas de la compra.
En la versión más sencilla, tras compilar la Lista de la Compra, la aplicación mostrará en qué Tiendas son más baratos los Artículos que el Usuario desea.
En primer lugar, cree un nuevo archivo llamado crear_artículo.característica en el características directorio. En la parte superior de un directorio .característica hay un archivo Característica seguida de una breve descripción de la misma. Por ejemplo:
Función: Creación de artículos
En las siguientes líneas puedes escribir un objetivo de negocio que implementará esta característica. Como Cucumber ignora el texto escrito antes del primer Escenario, no es necesario escribir nada, pero definitivamente es una buena idea.
Para crear fácilmente Listas de la Compra con Artículos vendidos en Tiendas cercanas
Como usuario
Quiero añadir artículos al sistema
En el fragmento anterior se puede ver un patrón bastante popular con el que se pueden describir los objetivos empresariales. Consta de tres partes: por qué es necesaria la función, quién la quiere y qué es. Por supuesto, no tienes por qué seguir este formato, pero asegúrate de incluir respuestas a estas tres preguntas en tu descripción.
Escenarios
A continuación, escribimos algunos escenarios. Cada escenario comienza con la palabra clave "Escenario" y contiene varios pasos.
Escenario: creación de un artículo único
Dado que existe un artículo "Leche
Cuando voy a la página principal
Y creo el artículo "Pan
Entonces veo "Pan" en la lista de artículos
Por lo tanto, si alguien ha creado un artículo llamado Leche, la creación de Pan es posible y da lugar a la aparición de Pan en la lista de artículos. No deberíamos probar la creación de un registro en la base de datos, ya que este hecho no tiene ningún valor real para el cliente.
Los pasos del escenario utilizan tres palabras clave principales:
Dadopara contextualizar el escenario
Enpara describir acciones
Entoncespara describir los resultados
Es importante tener en cuenta que Cucumber ignora la palabra clave paso con el que comienza y sólo coincide con la parte posterior. Por lo tanto, puede comenzar sus pasos con "Y" donde le parezca natural. La única regla para elegir la palabra clave correcta es que el Escenario debe ser fácilmente comprensible.
Definiciones de los pasos
La ejecución de Cucumber produce ahora este resultado:
[...]
Función: Creación de artículos
Para crear fácilmente Listas de la Compra con Artículos vendidos en Tiendas cercanas
Como usuario
Quiero añadir Artículos al sistema
Escenario: creación de un único artículo # features/create_item.feature:6
Dado que existe un artículo "Leche" # features/create_item.feature:7
Paso no definido: "existe un elemento "Leche"" (Cucumber::Undefined)
[...]
Esto se debe a que Cucumber no sabe lo que queremos decir cuando decimos "hay un artículo de leche". Para añadir algún significado a tus pasos necesitas definirlos en definiciones_paso directorio.
Una forma recomendada de organizar las definiciones de los pasos es dividirlos por dominios. Por ejemplo, la mayoría de los pasos que hemos creado, pertenecen al dominio Item. Por lo tanto, deberíamos crear un archivo llamado step_definitions/item_steps.rb y coloque allí el siguiente código:
Dado "existe un "$name" Item" do |name|
Fabricar :artículo, nombre: nombre
end
Dado "se crea "$name" Item" do |name|
dentro de "#nuevo_artículo" do
rellenar_en "Nombre", con: nombre
click_en "Crear"
end
end
Then "Veo "$name" en la lista de elementos" do |nombre|
dentro de ".items" do
expect(page).to have_content nombre
end
end
Las definiciones de los pasos suelen basarse en Capybara. Si no estás familiarizado con Capybara, asegúrate de consultar los enlaces al final de este artículo.
Hay un paso más que necesita definición y realmente no encaja dentro de los pasos de Item. Se podría poner en main_page_steps.rb:
Cuando "voy a la página principal" do
visitar ruta_raiz
fin
Conclusión
Esta es una historia muy simple para una característica muy simple. Su propósito era demostrar los conceptos básicos de BDD tal como se utilizan en Cucumber. Sin embargo, escribir buenas historias requiere un poco más. Como desarrollador, usted tendrá que cambiar su mentalidad por completo - olvidarse de la aplicación y centrarse en los objetivos de negocio en su lugar. Cucumber hace esta transición más fácil con su uso inteligente de historias de texto plano.