BDD de Aceptación con Ruby

168
Sergio Gil y Luismi Cavallé Pruebas BDD de Aceptación con Ruby Agile Spain 2010

description

Presented at AgileSpain 2010 in Madrid by Luismi Cavallé and Sergio Gil

Transcript of BDD de Aceptación con Ruby

Page 1: BDD de Aceptación con Ruby

Sergio Gil y Luismi Cavallé

Pruebas BDD de Aceptación con Ruby

Agile Spain 2010

Page 2: BDD de Aceptación con Ruby

Historias de Usuario

Page 3: BDD de Aceptación con Ruby

[A story] has to be a description of a requirement and its business benefit, and a set of criteria by which we all

agree that it is “done”

– Dan North

http://blog.dannorth.net/whats-in-a-story/

Page 4: BDD de Aceptación con Ruby

Anatomía de una historia

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Scenario: Buy last coffee Given there are 1 coffees left in the machine And I have deposited 1$ When I press the coffee button Then I should be served a coffee

Page 5: BDD de Aceptación con Ruby

Narrativa

Criterio de Aceptación

Anatomía de una historia

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Scenario: Buy last coffee Given there are 1 coffees left in the machine And I have deposited 1$ When I press the coffee button Then I should be served a coffee

Page 6: BDD de Aceptación con Ruby

Narrativa

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Page 7: BDD de Aceptación con Ruby

Título

Narrativa

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Page 8: BDD de Aceptación con Ruby

Rol¿Quién?

Narrativa

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Page 9: BDD de Aceptación con Ruby

Funcionalidad¿Qué?

Narrativa

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Page 10: BDD de Aceptación con Ruby

Beneficio¿Por qué?

Narrativa

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Page 11: BDD de Aceptación con Ruby

Regla de los 5 porqués

Page 12: BDD de Aceptación con Ruby

Regla de los 5 porqués

ENSÉÑAME LA PASTA !!!!

Page 13: BDD de Aceptación con Ruby

Criterio de Aceptación

Scenario: Buy last coffee

Given there are 1 coffees left in the machine And I have deposited 1$

When I press the coffee button

Then I should be served a coffee

Page 14: BDD de Aceptación con Ruby

Contexto

Criterio de Aceptación

Scenario: Buy last coffee

Given there are 1 coffees left in the machine And I have deposited 1$

When I press the coffee button

Then I should be served a coffee

Page 15: BDD de Aceptación con Ruby

Eventos

Criterio de Aceptación

Scenario: Buy last coffee

Given there are 1 coffees left in the machine And I have deposited 1$

When I press the coffee button

Then I should be served a coffee

Page 16: BDD de Aceptación con Ruby

Resultados

Criterio de Aceptación

Scenario: Buy last coffee

Given there are 1 coffees left in the machine And I have deposited 1$

When I press the coffee button

Then I should be served a coffee

Page 17: BDD de Aceptación con Ruby

Criterio de Aceptación

Scenario: Buy last coffee

Given there are 1 coffees left in the machine And I have deposited 1$

When I press the coffee button

Then I should be served a coffee

DONE

Page 18: BDD de Aceptación con Ruby

Beneficio para el negocio

TestersProgramadores

ManagersClientesAnalistas

Page 19: BDD de Aceptación con Ruby

Beneficio para el negocio

Historia de UsuarioToken de comunicación / discusiónPriorización según beneficio / valor

Criterio común de “terminado”

TestersProgramadores

ManagersClientesAnalistas

Page 20: BDD de Aceptación con Ruby

Cucumber

Page 21: BDD de Aceptación con Ruby

Cucumber

Feature: Serve coffee In order to earn money Customers should be able to buy coffee at all times

Scenario: Buy last coffee Given there are 1 coffees left in the machine And I have deposited 1$ When I press the coffee button Then I should be served a coffee

Page 22: BDD de Aceptación con Ruby

Pasos

Given a user “john” with password “secret”

When he tries to login as “james”

Then he should see an error message

Page 23: BDD de Aceptación con Ruby

Definición de pasos

Given a user “john” with password “secret”

Page 24: BDD de Aceptación con Ruby

Definición de pasos

Given /^a user "(.+)" with password "(.+)"$/ do |login, password|

Given a user “john” with password “secret”

Page 25: BDD de Aceptación con Ruby

Definición de pasos

Given /^a user "(.+)" with password "(.+)"$/ do |login, password| User.create! :login => login, :password => passwordend

Given a user “john” with password “secret”

Page 26: BDD de Aceptación con Ruby

Definición de pasos

When he tries to login as “james”

Page 27: BDD de Aceptación con Ruby

Definición de pasos

When /^he tries to login as "(.+)"$/ do |login|

When he tries to login as “james”

Page 28: BDD de Aceptación con Ruby

Definición de pasos

When /^he tries to login as "(.+)"$/ do |login| visit "/login" fill_in "Username", :with => login fill_in "Password", :with => "secret" click_button "Login"end

When he tries to login as “james”

Page 29: BDD de Aceptación con Ruby

Definición de pasos

Then he should see an error message

Page 30: BDD de Aceptación con Ruby

Definición de pasos

Then he should see an error message

Then /^I should see an error message$/ do

Page 31: BDD de Aceptación con Ruby

Definición de pasos

Then he should see an error message

Then /^I should see an error message$/ do assert page.has_content?("Invalid credentials")end

Page 32: BDD de Aceptación con Ruby

Demo

Page 33: BDD de Aceptación con Ruby

http://vimeo.com/12441999

Page 34: BDD de Aceptación con Ruby

+40 Idiomas

# language: esCaracterística: Búsqueda de cursos Para asegurar el mejor uso de los cursos Los estudiantes potenciales deberían poder buscar cursos Escenario: Búsqueda por materia Dado que hay 240 cursos, ninguno sobre "biología" Y hay 2 cursos A001, B205 sobre "biología" Cuando busco por "biología" Entonces debería ver los siguientes cursos: | Código de curso | | A001 | | B205 |

Page 35: BDD de Aceptación con Ruby

Otros lenguajes package cukes;

import cuke4duke.Given;import java.util.List;import java.util.ArrayList;

public class BellySteps { private List<String> belly = new ArrayList<String>();

@Given("I have (\\d+) cukes in my belly") public void bellyCukes(int cukes) { for(int i = 0; i < cukes; i++) { belly.add("cuke " + i); } }}

Page 36: BDD de Aceptación con Ruby

Otros lenguajes package cukes;

import cuke4duke.Given;import java.util.List;import java.util.ArrayList;

public class BellySteps { private List<String> belly = new ArrayList<String>();

@Given("I have (\\d+) cukes in my belly") public void bellyCukes(int cukes) { for(int i = 0; i < cukes; i++) { belly.add("cuke " + i); } }}

(Given #"^I have entered ([\d.]+) into the calculator$" (fn [number] (push-number (Float. number))))

Page 37: BDD de Aceptación con Ruby

Más funcionalidades...

Page 38: BDD de Aceptación con Ruby

Background

Feature: Multiple blog support Background: Given a global administrator named "Greg" And a blog named "Greg's anti-tax rants" And a customer named "Dr. Bill" And a blog named "Expensive Therapy" owned by "Dr. Bill" Scenario: Dr. Bill posts to his own blog Scenario: Dr. Bill tries to post to somebody else's blog Scenario: Greg posts to a client's blog

Page 39: BDD de Aceptación con Ruby

Tags

$ cucumber --tags @billing,~@important

@billingFeature: Verify billing

@important Scenario: Missing product description

Scenario: Several products

Page 40: BDD de Aceptación con Ruby

HooksBefore do @browser = Browser.newend

After do @browser.closeend

Page 41: BDD de Aceptación con Ruby

HooksBefore do @browser = Browser.newend

After do @browser.closeend

Around do |scenario, block| Timeout.timeout(3) do block.call endend

Page 42: BDD de Aceptación con Ruby

HooksBefore do @browser = Browser.newend

After do @browser.closeend

Around do |scenario, block| Timeout.timeout(3) do block.call endend

Before('@foo')

After('~@bar')

Page 43: BDD de Aceptación con Ruby

Scenario Outline

Scenario Outline: eating Given there are <start> cucumbers When I eat <eat> cucumbers Then I should have <left> cucumbers

Examples: | start | eat | left | | 12 | 5 | 7 | | 20 | 5 | 15 |

Page 44: BDD de Aceptación con Ruby

So far, so good?

• Historias de Usuario

• Beneficio para el negocio

• Cucumber

Page 45: BDD de Aceptación con Ruby

So far, so good?

Coming next...• Testing de aceptación Web

• Beneficio para los devs

• Alternativas a Cucumber

• Historias de Usuario

• Beneficio para el negocio

• Cucumber

Page 46: BDD de Aceptación con Ruby

Aceptación para Web:Capybara

Page 47: BDD de Aceptación con Ruby

DSL de interacción web (navegador programático)

Page 48: BDD de Aceptación con Ruby

Usa el lenguaje del usuario

classmethod

GET / POSTparameters

Page 49: BDD de Aceptación con Ruby

Usa el lenguaje del usuario

classmethod

GET / POSTparameters

pageURLlink

form

Page 50: BDD de Aceptación con Ruby

visit "/wadus"

Page 51: BDD de Aceptación con Ruby
Page 52: BDD de Aceptación con Ruby

click_link "Add article"

Page 53: BDD de Aceptación con Ruby

click_link "Add article"click "Add article"

Page 54: BDD de Aceptación con Ruby
Page 55: BDD de Aceptación con Ruby

fill_in "Title", :with => "Wadus"

Page 56: BDD de Aceptación con Ruby

fill_in "Title", :with => "Wadus"choose "Option"

Page 57: BDD de Aceptación con Ruby

fill_in "Title", :with => "Wadus"choose "Option"check "Option"

Page 58: BDD de Aceptación con Ruby

fill_in "Title", :with => "Wadus"choose "Option"check "Option"uncheck "Option"

Page 59: BDD de Aceptación con Ruby

fill_in "Title", :with => "Wadus"choose "Option"check "Option"uncheck "Option"select "1980", :from => "Birth Year"

Page 60: BDD de Aceptación con Ruby

fill_in "Title", :with => "Wadus"choose "Option"check "Option"uncheck "Option"select "1980", :from => "Birth Year"click_button "Save"

Page 61: BDD de Aceptación con Ruby

fill_in "Title", :with => "Wadus"choose "Option"check "Option"uncheck "Option"select "1980", :from => "Birth Year"click_button "Save"click "Save"

Page 62: BDD de Aceptación con Ruby

within :css, ".article:first" do click_link "Edit"end

Page 63: BDD de Aceptación con Ruby

Matchers

Page 64: BDD de Aceptación con Ruby

page.should have_content("Wadus")

Page 65: BDD de Aceptación con Ruby

page.should have_content("Wadus")page.should_not have_content("Wadus")

Page 66: BDD de Aceptación con Ruby

page.should have_content("Wadus")page.should_not have_content("Wadus")

page.should have_css(".article", :text => "Wadus")

Page 67: BDD de Aceptación con Ruby

page.should have_content("Wadus")page.should_not have_content("Wadus")

page.should have_css(".article", :text => "Wadus")page.should have_css(".article", :count => 3)

Page 68: BDD de Aceptación con Ruby

page.should have_content("Wadus")page.should_not have_content("Wadus")

page.should have_css(".article", :text => "Wadus")page.should have_css(".article", :count => 3)

page.should have_xpath("//*[@class='article']")

Page 69: BDD de Aceptación con Ruby

page.should have_css(".article", :text => "Wadus") do |article| article.should have_css(".author", :text => "@porras") article.should have_css(".links") do |links| links.should have_css("a", :href => "http://wadus.info") links.should have_css("a", :href => "http://bit.ly/wadus") endend

Page 70: BDD de Aceptación con Ruby

save_and_open_page

Page 71: BDD de Aceptación con Ruby

Drivers

Page 72: BDD de Aceptación con Ruby

RackTest

Page 73: BDD de Aceptación con Ruby

RackTest

Basado en Rack

Page 74: BDD de Aceptación con Ruby

RackTest

FAST!

Basado en Rack

Page 75: BDD de Aceptación con Ruby

RackTest

FAST!Sin Javascript

Basado en Rack

Page 76: BDD de Aceptación con Ruby

RackTest

FAST!Sin Javascript

No es ‘real’

Basado en Rack

Page 77: BDD de Aceptación con Ruby

Selenium

Page 78: BDD de Aceptación con Ruby

Selenium

Basado en browsers programables

Page 79: BDD de Aceptación con Ruby

Selenium

Javascript

Basado en browsers programables

Page 80: BDD de Aceptación con Ruby

Selenium

JavascriptAceptación pura

Basado en browsers programables

Page 81: BDD de Aceptación con Ruby

Selenium

JavascriptAceptación pura

¡LENTO!

Basado en browsers programables

Page 82: BDD de Aceptación con Ruby

Selenium

JavascriptAceptación pura

¡LENTO!Un poco frágil

Basado en browsers programables

Page 83: BDD de Aceptación con Ruby

Selenium

JavascriptAceptación pura

¡LENTO!Un poco frágil

Java

Basado en browsers programables

Page 84: BDD de Aceptación con Ruby

Celerity / Culerity

Page 85: BDD de Aceptación con Ruby

Celerity / Culerity

Basado en HTMLUnit

Page 86: BDD de Aceptación con Ruby

Celerity / Culerity

Javascript

Basado en HTMLUnit

Page 87: BDD de Aceptación con Ruby

Celerity / Culerity

JavascriptAceptación casi pura

Basado en HTMLUnit

Page 88: BDD de Aceptación con Ruby

Celerity / Culerity

JavascriptAceptación casi pura

No muy lento

Basado en HTMLUnit

Page 89: BDD de Aceptación con Ruby

Celerity / Culerity

JavascriptAceptación casi pura

No muy lentoJava

Basado en HTMLUnit

Page 90: BDD de Aceptación con Ruby

Envjs

Page 91: BDD de Aceptación con Ruby

Envjs

Basado en SpiderMonkey

Page 92: BDD de Aceptación con Ruby

Envjs

Basado en SpiderMonkey

Javascript

Page 93: BDD de Aceptación con Ruby

Envjs

Basado en SpiderMonkey

JavascriptAceptación casi pura

Page 94: BDD de Aceptación con Ruby

Envjs

Basado en SpiderMonkey

JavascriptAceptación casi pura

No muy lento

Page 95: BDD de Aceptación con Ruby

Envjs

Basado en SpiderMonkey

JavascriptAceptación casi pura

No muy lentoRuby

Page 96: BDD de Aceptación con Ruby

Envjs

Basado en SpiderMonkey

JavascriptAceptación casi pura

No muy lentoRuby

Un poco verde

Page 97: BDD de Aceptación con Ruby

RackTest

Selenium

Culerity

0 37.5 75.0 112.5 150.0

Page 98: BDD de Aceptación con Ruby

Valor para el desarrollador

Page 99: BDD de Aceptación con Ruby

Excelente herramienta de verificación

Page 100: BDD de Aceptación con Ruby

Pero TDD no es QA

Page 101: BDD de Aceptación con Ruby

Pero TDD no es QAsólo

Page 102: BDD de Aceptación con Ruby

Dirige el desarrollo

Page 103: BDD de Aceptación con Ruby

“Outside-in testing is the best way to avoid overengineering”

http://www.sarahmei.com/blog/2010/05/29/outside-in-bdd/

Page 104: BDD de Aceptación con Ruby

Up-front

Page 105: BDD de Aceptación con Ruby

M

Up-front

Page 106: BDD de Aceptación con Ruby

C

M

Up-front

Page 107: BDD de Aceptación con Ruby

V

C

M

Up-front

Page 108: BDD de Aceptación con Ruby

V

C

M

T

Up-front

Page 109: BDD de Aceptación con Ruby

V

C

M

TT

Up-front

Page 110: BDD de Aceptación con Ruby

V

C

M

TTT

Up-front

Page 111: BDD de Aceptación con Ruby

Outside-in

Page 112: BDD de Aceptación con Ruby

F

Outside-in

Page 113: BDD de Aceptación con Ruby

F

V

Outside-in

Page 114: BDD de Aceptación con Ruby

F

V

C

Outside-in

Page 115: BDD de Aceptación con Ruby

F

V

CM

Outside-in

Page 116: BDD de Aceptación con Ruby

F

V

CM

F

V

CM

F

V

CM

F

V

CM

F

V

CM

Outside-in

Page 117: BDD de Aceptación con Ruby

“Tu interfaz es tu producto”

http://gettingreal.37signals.com/ch09_Interface_First.php

Page 118: BDD de Aceptación con Ruby

Permite otras prácticas ágiles

Page 119: BDD de Aceptación con Ruby

The Simplest Thing That Could Possibly Work

Page 120: BDD de Aceptación con Ruby

Dejar que el diseño “emerja”

Page 121: BDD de Aceptación con Ruby

Pair Programming

Page 122: BDD de Aceptación con Ruby

Refactorización contínua

Page 123: BDD de Aceptación con Ruby

Integración Contínua

Page 124: BDD de Aceptación con Ruby

Propiedad colectiva del código

Page 125: BDD de Aceptación con Ruby

Release Often

Page 126: BDD de Aceptación con Ruby

Continuous Deployment

Page 127: BDD de Aceptación con Ruby

Steak

Page 128: BDD de Aceptación con Ruby

A veces Cucumber (historias en texto plano)

no es la mejor opción

Page 129: BDD de Aceptación con Ruby

Todo el “valor para el desarrollador” sin la

burocracia extra

Page 130: BDD de Aceptación con Ruby

feature "Main page" do

background do create_user :login => "wadus" end

scenario "should show existing books" do create_book :title => "The Pragmatic Programmer"

login_as "wadus" visit "/"

page.should have_css(".book", :text => "The Pragmatic Programmer") end

end

Page 131: BDD de Aceptación con Ruby

feature "Main page" do

background do create_user :login => "wadus" end

scenario "should show existing books" do create_book :title => "The Pragmatic Programmer"

login_as "wadus" visit "/"

page.should have_css(".book", :text => "The Pragmatic Programmer") end

end

Page 132: BDD de Aceptación con Ruby

feature "Main page" do

background do create_user :login => "wadus" end

scenario "should show existing books" do create_book :title => "The Pragmatic Programmer"

login_as "wadus" visit "/"

page.should have_css(".book", :text => "The Pragmatic Programmer") end

end

Page 133: BDD de Aceptación con Ruby

feature "Main page" do

background do create_user :login => "wadus" end

scenario "should show existing books" do create_book :title => "The Pragmatic Programmer"

login_as "wadus" visit "/"

page.should have_css(".book", :text => "The Pragmatic Programmer") end

end

Page 134: BDD de Aceptación con Ruby

feature "Main page" do

background do create_user :login => "wadus" end

scenario "should show existing books" do create_book :title => "The Pragmatic Programmer"

login_as "wadus" visit "/"

page.should have_css(".book", :text => "The Pragmatic Programmer") end

end

Page 135: BDD de Aceptación con Ruby

feature "Main page" do

background do create_user :login => "wadus" end

scenario "should show existing books" do create_book :title => "The Pragmatic Programmer"

login_as "wadus" visit "/"

page.should have_css(".book", :text => "The Pragmatic Programmer") end

end

Page 136: BDD de Aceptación con Ruby

feature "Main page" do

background do create_user :login => "wadus" end

scenario "should show existing books" do create_book :title => "The Pragmatic Programmer"

login_as "wadus" visit "/"

page.should have_css(".book", :text => "The Pragmatic Programmer") end

end

Page 137: BDD de Aceptación con Ruby

Demo

Page 138: BDD de Aceptación con Ruby

http://vimeo.com/12468092

Page 139: BDD de Aceptación con Ruby

Más amigos

Page 140: BDD de Aceptación con Ruby

Spork

Page 141: BDD de Aceptación con Ruby

Spork

Sin spork

Con spork

0 3.25 6.50 9.75 13.00

Page 142: BDD de Aceptación con Ruby

Factorías

Page 143: BDD de Aceptación con Ruby
Page 144: BDD de Aceptación con Ruby

fixture_replacement

Page 145: BDD de Aceptación con Ruby

fixture_replacementfactory_girl

Page 146: BDD de Aceptación con Ruby

fixture_replacementfactory_girlmachinist

Page 147: BDD de Aceptación con Ruby

fixture_replacementfactory_girlmachinistfixjour

Page 148: BDD de Aceptación con Ruby

fixture_replacementfactory_girlmachinistfixjourcranky

Page 149: BDD de Aceptación con Ruby

fixture_replacementfactory_girlmachinistfixjourcranky

Ruby

Page 150: BDD de Aceptación con Ruby

module Factories def create_user(attrs = {}) attrs = attrs.dup attrs[:name] ||= String.random(10) attrs[:email] ||= "#{String.random(10)}@example.com" User.create!(attrs) end def create_article(attrs = {}) attrs = attrs.dup attrs[:title] ||= String.random(10) attrs[:author] ||= create_user Article.create!(attrs) end end

...

create_usercreate_user(:name => "Bartolo")create_articlecreate_article(:author => create_user(:name => "Mr. Wadus"))

Page 151: BDD de Aceptación con Ruby

Delorean

Page 152: BDD de Aceptación con Ruby

Delorean

Page 153: BDD de Aceptación con Ruby

Delorean

it "should show latest created user" do time_travel_to(3.minutes.ago) { create_user :name => "John" } time_travel_to(5.minutes.ago) { create_user :name => "Chris" }

get '/'

page.should have_content("John") page.should_not have_content("Chris")end

Page 154: BDD de Aceptación con Ruby

Database Cleaner

Page 155: BDD de Aceptación con Ruby

Database Cleaner

DatabaseCleaner.strategy = :truncationDatabaseCleaner.clean

Page 156: BDD de Aceptación con Ruby

Database Cleaner

DatabaseCleaner.strategy = :transactionDatabaseCleaner.clean

Page 157: BDD de Aceptación con Ruby

Email Spec

Page 158: BDD de Aceptación con Ruby

Email Spec

mailbox_for("[email protected]").should have(1).email

open_email "[email protected]"

current_email.should have_subject("Bienvenido a Wadus 2.0")current_email.should have_text("Hola, porras")

Page 159: BDD de Aceptación con Ruby

Webmock

Page 160: BDD de Aceptación con Ruby

Webmock

request(:post, "www.example.com"). with(:body => "abc"). should have_been_made.once

Page 161: BDD de Aceptación con Ruby

MundoPepino

Page 162: BDD de Aceptación con Ruby

“MundoPepino es un conjunto de pasos genéricos para testear una

aplicación Rails utilizando Cucumber”

Page 163: BDD de Aceptación con Ruby

Dado que tenemos un huertoY una huertaY un huerto "En el río"Y una huerta "En el castro"Y un huerto llamado "Regadío"Y una huerta llamada "Secano"Y 2 huertosY 2 huertos "Regadío"Y 2 huertos llamados "Secano"Y 2 huertas llamadas "Secano"Y 3 huertas llamadas "H-01, H-02 y H-03"Entonces tenemos en bbdd 17 huertosY tenemos en bbdd un huerto "En el río"Y tenemos en bbdd una huerta "En el castro"Y tenemos en bbdd 3 huertos "Regadío"Y tenemos en bbdd 5 huertas "Secano"Y tenemos en bbdd un huerto "H-01"Y tenemos en bbdd un huerto "H-02"Y tenemos en bbdd un huerto "H-03"

Page 164: BDD de Aceptación con Ruby

Cuando visito la página de creación de huertoEntonces debo ver la etiqueta H2 con el valor "Alta de Huerta"Cuando visito la página de alta de huertoEntonces debo ver la etiqueta H2 con el valor "Alta de Huerta"Cuando visito la página de nueva huertaEntonces debo ver la etiqueta H2 con el valor "Alta de Huerta"

Dado que visito la página de creación de huertoEntonces debo ver la etiqueta H2 con el valor "Alta de Huerta"

Page 165: BDD de Aceptación con Ruby

Dado que tenemos un huerto llamado "H-01"Y que dicho huerto tiene los siguientes aspersores: | nombre | caudal | unidad caudal || A-01 | 15 | m3 || A-02 | 12 | m3 || B-01 | 10 | m3 |Entonces tenemos en bbdd un huertoY tenemos en bbdd tres aspersoresY el huerto "H-01" tiene en bbdd un aspersor "A-01"Y el aspersor "A-01" tiene en bbdd como caudal "15"Y tiene en bbdd como unidad caudal "m3"Y el huerto "H-01" tiene en bbdd un aspersor "A-02"Y el aspersor "A-02" tiene en bbdd como caudal "12"Y tiene en bbdd como unidad caudal "m3"Y el huerto "H-01" tiene en bbdd un aspersor "B-01"Y el aspersor "B-01" tiene en bbdd como caudal "10"Y tiene en bbdd como unidad caudal "m3"

Page 166: BDD de Aceptación con Ruby

Recapitulando

• Aceptación Web

• Valor para los devs

• Steak (‘cause Cucumber

is for veggies)

• Otros amiguitos...

• Testing de aceptación Web

• Beneficio para los devs

• Alternativas a Cucumber

Page 167: BDD de Aceptación con Ruby

Gracias!

Page 168: BDD de Aceptación con Ruby

Gracias!

¿Preguntas?

Agile Spain 2010

@porras y @cavalle