« Previous -
Version 31/40
(diff) -
Next » -
Current version
Guillermo Gómez, 02/15/2012 06:47 pm
Cucumber¶
Behaviour Driven Development (BDD).
- http://cukes.info/
- http://cuke4ninja.com
- http://eggsonbread.com/2010/09/06/my-cucumber-best-practices-and-tips/
Instalación¶
# yum install rubygem-cucumber
BDD ejemplo¶
$ mkdir cucumber-1 $ cd cucumber-1 $ mkdir features $ mkdir features/step_definitions
Describa el comportamiento en texto plano¶
Cucumber es una herramienta que ejecuta descripciones funcionales en texto plano como pruebas automatizadas. El lenguaje que Cucumber entiende se conoce como Gherkin.
features/f1.feature
1# language: es
2Característica: Buscar en cursos
3 Con la finalidad de asegurar una mejor utilización de los cursos
4 Los estudiantes potenciales deben ser capaces de realizar búsqueda en los cursos
5
6Escenario: Búsqueda por tema
7 Dado que hay cursos que no tienen el tema "biología"
8 Y que hay 2 cursos , A001, B205, que cada uno tiene "biología" como uno de sus temas
9 Cuando yo busque por "biología"
10 Entonces yo debería ver los siguientes cursos:
11 | Id. del curso |
12 | A001 |
13 | B205 |
Corrida de prueba¶
$ cucumber features/f1.feature
# language: es
Característica: Buscar en cursos
Con la finalidad de asegurar una mejor utilización de los cursos
Los estudiantes potenciales deben ser capaces de realizar búsqueda en los cursos
Escenario: Búsqueda por tema # features/f1.feature:6
Dado que hay cursos que no tienen el tema "biología" # features/f1.feature:7
Y que hay 2 cursos , A001, B205, que cada uno tiene "biología" como uno de sus temas # features/f1.feature:8
Cuando yo busque por "biología" # features/f1.feature:9
Entonces yo debería ver los siguientes cursos: # features/f1.feature:10
| Id. del curso |
| A001 |
| B205 |
1 scenario (1 undefined)
4 steps (4 undefined)
0m0.007s
You can implement step definitions for undefined steps with these snippets:
Dado /^que hay cursos que no tienen el tema "([^"]*)"$/ do |arg1|
pending # express the regexp above with the code you wish you had
end
Dado /^que hay (\d+) cursos , A(\d+), B(\d+), que cada uno tiene "([^"]*)" como uno de sus temas$/ do |arg1, arg2, arg3, arg4|
pending # express the regexp above with the code you wish you had
end
Cuando /^yo busque por "([^"]*)"$/ do |arg1|
pending # express the regexp above with the code you wish you had
end
Entonces /^yo debería ver los siguientes cursos:$/ do |table|
# table is a Cucumber::Ast::Table
pending # express the regexp above with the code you wish you had
end
If you want snippets in a different programming language, just make sure a file
with the appropriate file extension exists where cucumber looks for step definitions.
Entorno¶
Antes de crear los archivos de definiciones de pasos, cree el archivo features/support/env.rb con el siguiente contenido:
1require 'rubygems'
Escriba la definición de paso en Ruby¶
- Gherkin Definiciones de paso
- http://gem-session.com/2010/04/never-write-a-cucumber-step-definition-again-with-cucumber-factory
- https://gist.github.com/414051
Cree un subdirectorio step_definitions y un primer archivo de definiciones de paso como features/step_definitions/basic_steps.rb .
1Dado /^que hay cursos que no tienen el tema "([^"]*)"$/ do |arg1|
2 pending # express the regexp above with the code you wish you had
3end
4
5Dado /^que hay (\d+) cursos , A(\d+), B(\d+), que cada uno tiene "([^"]*)" como uno de sus temas$/ do |arg1, arg2, arg3, arg4|
6 pending # express the regexp above with the code you wish you had
7end
8
9Cuando /^yo busque por "([^"]*)"$/ do |arg1|
10 pending # express the regexp above with the code you wish you had
11end
12
13Entonces /^yo debería ver los siguientes cursos:$/ do |table|
14 # table is a Cucumber::Ast::Table
15 pending # express the regexp above with the code you wish you had
16end
Nueva corrida¶
$ cucumber features/f1.feature
# language: es
Característica: Buscar en cursos
Con la finalidad de asegurar una mejor utilización de los cursos
Los estudiantes potenciales deben ser capaces de realizar búsqueda en los cursos
Escenario: Búsqueda por tema # features/f1.feature:6
Dado que hay cursos que no tienen el tema "biología" # features/step_definitions/f1-sd.rb:2
TODO (Cucumber::Pending)
./features/step_definitions/f1-sd.rb:3:in `/^que hay cursos que no tienen el tema "([^"]*)"$/'
features/f1.feature:7:in `Dado que hay cursos que no tienen el tema "biología"'
Y que hay 2 cursos , A001, B205, que cada uno tiene "biología" como uno de sus temas # features/step_definitions/f1-sd.rb:6
Cuando yo busque por "biología" # features/step_definitions/f1-sd.rb:10
Entonces yo debería ver los siguientes cursos: # features/step_definitions/f1-sd.rb:14
| Id. del curso |
| A001 |
| B205 |
1 scenario (1 pending)
4 steps (3 skipped, 1 pending)
0m0.008s
Note el TODO, esto es lo primero que hay que implementar, excelente, Cucumber nos está diciendo qué es lo debemos implementar. Comencemos! Volvamos sobre nuestro archivo de definiciones de paso y sigamos la sugerencia pending # express the regexp above with the code you wish you had .
Esto significa, escriba código Ruby de cómo usted quisiera que funcione, para mi esto significa ahora lo siguiente, para el paso 1.
1Dado /^que hay cursos que no tienen el tema "([^"]*)"$/ do |arg1|
2 Curso.search_by_topic("!#{arg1}").size > 0
3end
Al volver a correr nuevamente nuestra funcionalidad o característica podemos extraer:
...
Escenario: Búsqueda por tema # features/f1.feature:6
Dado que hay cursos que no tienen el tema "biología" # features/step_definitions/f1-sd.rb:2
uninitialized constant Curso (NameError)
./features/step_definitions/f1-sd.rb:3:in `/^que hay cursos que no tienen el tema "([^"]*)"$/'
features/f1.feature:7:in `Dado que hay cursos que no tienen el tema "biología"'
...
Por supuesto, aún no se implementa la clase Curso. Es momento de comenzar la verdadera implementación, creemos curso.rb e iterando podemos ir desarrolando hasta hacer pasar el paso 1, recuerde agregar el require 'curso' en el archivo de definiciones de paso. Mi clase Curso entonces va así y el resultado de volver a correr la funcionalidad justo después.
1class Curso
2 def self.search_by_topic(tema)
3 # Devuelve un arreglo con los cursos
4 res = Array.new
5 res
6 end
7end
$ cucumber features/f1.feature
# language: es
Característica: Buscar en cursos
Con la finalidad de asegurar una mejor utilización de los cursos
Los estudiantes potenciales deben ser capaces de realizar búsqueda en los cursos
Escenario: Búsqueda por tema # features/f1.feature:6
Dado que hay cursos que no tienen el tema "biología" # features/step_definitions/f1-sd.rb:3
Y que hay 2 cursos , A001, B205, que cada uno tiene "biología" como uno de sus temas # features/step_definitions/f1-sd.rb:7
TODO (Cucumber::Pending)
./features/step_definitions/f1-sd.rb:8:in `/^que hay (\d+) cursos , A(\d+), B(\d+), que cada uno tiene "([^"]*)" como uno de sus temas$/'
features/f1.feature:8:in `Y que hay 2 cursos , A001, B205, que cada uno tiene "biología" como uno de sus temas'
Cuando yo busque por "biología" # features/step_definitions/f1-sd.rb:11
Entonces yo debería ver los siguientes cursos: # features/step_definitions/f1-sd.rb:15
| Id. del curso |
| A001 |
| B205 |
1 scenario (1 pending)
4 steps (2 skipped, 1 pending, 1 passed)
Note que ya el prime paso "pasa", de hecho se ha ejecutado (revisado) el código implementado, también note que la implementación es trivialmente simple para poder cumplir con la especificación de "cómo quisiera mi código", su comportamiento.
Para el segundo paso se me ocurre:
Dado /^que hay (\d+) cursos , A(\d+), B(\d+), que cada uno tiene "([^"]*)" como uno de sus temas$/ do |arg1, arg2, arg3, arg4|
Curso.search_by_id("#{arg2}").topics.include?("#{arg4}") == true
Curso.search_by_id("#{arg3}").topics.include?("#{arg4}") == true
end
Para ello implemento:
1class Curso
2 def self.search_by_id(curso_id)
3 # Temporalmente solo devuelve un Curso
4 curso = Curso.new
5 curso
6 end
7
8 def initialize
9 # Cursos son implementados por medio de por ejemplo un ORM como AR
10 # Los temas son simplemente representandos por un arreglo de strings
11 @topics = Array.new
12 end
13
14 def topics
15 @topics
16 end
17end
Nueva corrida:
$ cucumber features/f1.feature
# language: es
Característica: Buscar en cursos
Con la finalidad de asegurar una mejor utilización de los cursos
Los estudiantes potenciales deben ser capaces de realizar búsqueda en los cursos
Escenario: Búsqueda por tema # features/f1.feature:6
Dado que hay cursos que no tienen el tema "biología" # features/step_definitions/f1-sd.rb:3
Y que hay 2 cursos , A001, B205, que cada uno tiene "biología" como uno de sus temas # features/step_definitions/f1-sd.rb:7
Cuando yo busque por "biología" # features/step_definitions/f1-sd.rb:12
TODO (Cucumber::Pending)
./features/step_definitions/f1-sd.rb:13:in `/^yo busque por "([^"]*)"$/'
features/f1.feature:9:in `Cuando yo busque por "biología"'
Entonces yo debería ver los siguientes cursos: # features/step_definitions/f1-sd.rb:16
| Id. del curso |
| A001 |
| B205 |
1 scenario (1 pending)
4 steps (1 skipped, 1 pending, 2 passed)
0m0.008s
Resta el tercer paso (TODO).
