Einführung in Cucumber mit Rails. Vortrag wurde am 30.06.2009 an der
Heinrich-Heine-Universität Düsseldorf im Rahmen der Rails User Group Düsseldorf von Tanja Otto und Hussein Morsy gehalten
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Einführung in Cucumber mit Rails
1. Cucumber
Hussein Morsy und Tanja Otto
30.06.2009
Heinrich-Heine-Universität Düsseldorf
Rails User Group Düsseldorf
2. Über uns
• internes Entwicklerteam von Sales-Lentz
• IBEs für Reisen, Bustickets, Eventtickets
• seit 2006 entwickeln wir mit Ruby on Rails
• Buch Ruby on Rails 2 Galileo Press
http://www.railsbuch.de
4. Aufbau
• Philosophie
• Cucumber Features erstellen
• Cucumber Features automatisieren
• Tabellen, Outlines und weitere Helferleins
• Cucumber installieren und konfigurieren
• Demo
6. Was ist TDD
• Hauptmerkmal: Test First
• Von Innen nach Aussen
• Red => Green => Refactor
“Make it green than make it clean”
• TDD ist kein Test-Tool, sondern eine
Technik für Entwickler
7. Units
Views Views Views Views
Controller Controller Controller
Model Model Model Model Model
10. Was ist BDD
• BDD ist kein Ersatz für TDD
• TDD ist ein Bestandteil von BDD
• BDD bedeutet outside-in Entwicklung
• Wie ein User mit der App arbeiten möchte
beeinflusst die Implementierung
• Kundenwünsche stehen an erster Stelle
11. Outside-In
Views Views Views Views
Controller Controller Controller
Model Model Model Model Model
14. Planung
• Beschreibung der Features bzw.
Akzeptanzkritieren
• Beschreibung einer Story aus
Anwendersicht
• Zusammen mit dem Kunden
• Business Value steht an erster Stelle
• Wenn Kritieren erfüllt => Akzeptiert
15. Merkmale
• Beschreibung der Features/
Akzeptanzkriterien in Prosaform
• Automatisiertes ausführen der Features
• Unterstützung von mehreren Sprachen
• Nicht nur für Rails (Java, .Net, Erlang, ... )
22. Scenario: booking a Travel
Given a travel “Rhein in Flammen” for 137.40
When I go to the detail page of Rhein in Flammen
When I follow "buchen"
When I select "Herr" from "Anrede"
When I fill in "Nachname" with "Mustermann"
When I fill in "E-Mail" with "hans@mustermann.de"
When I check "Versicherung"
When I press "buchen"
Then I should see "Ihre Buchung"
Then I should see "Herr"
Then I should see "Mustermann"
Then I should see "hans@mustermann.de"
Then I should see "137,40 EUR"
Then I should not see "Ausgebucht"
23. Scenario: booking a Travel
Given a travel “Rhein in Flammen” for 137.40
When I go to the detail page of Rhein in Flammen
And I follow "buchen"
And I select "Herr" from "Anrede"
And I fill in "Nachname" with "Mustermann"
And I fill in "E-Mail" with "hans@mustermann.de"
And I check "Versicherung"
And I press "buchen"
Then I should see "Ihre Buchung"
And I should see "Herr"
And I should see "Mustermann"
And I should see "hans@mustermann.de"
And I should see "137,40 EUR"
But I should not see "Ausgebucht"
24. Aufbau eines Szenarios
• Titel (Scenario:)
• Steps
• Vorbedingungen (Given)
• Aktionen (When)
• Erwartungen (Then)
26. Feature: Administrationsbereich
Als ein angemeldeter Administrator
Möchte ich die Admin-Seiten besuchen
So dass ich die Seiten leicht aktualisieren kann.
Szenario: Zugang für Admin-Seite beschränken
Gegeben sei ein Admin-User
Wenn ich nicht eingelogged bin
Und ich die Admin-Seite besuche
Dann sollte mir der Zugang verweigert werden
Szenario: Zugang für für autorisierten User
Gegeben sei ein Admin-User
Und ich bin eingelogged als Admin-User
Wenn ich die Admin-Seite besuche
Dann sollte ich "Admin-Bereich" sehen
30. Given-Step mit Definition
Step
Given a travel “Rhein in Flammen” for 137.40
Step-Definition
Given /^a travel "([^"]*)" for ([0-9.]*)$/ do |title, price|
Travel.create(:title => title, :price => price.to_f)
end
31. Given Step-Definition
• Hier werden meist die Daten vorbereitet
• Implementierung meist mit ActiveRecord
Given /^a travel "([^"]*)" for ([0-9.]*)$/ do |title, price|
Travel.create(:title => title, :price => price.to_f)
end
33. When Step-Definition
• Hier findet die Interaktion statt
• Simulation des Browsers
• Implementierung z.B. mit Webrat
When /^I press "([^"]*)"$/ do |button|
click_button(button)
end
34. Then-Step mit Definition
Step
Then I should see "Ihre Buchung"
Step-Definition
Then /^I should see "([^"]*)"$/ do |text|
response.should contain(text)
end
35. Then Step-Definition
• Hier wird geprüft, ob eine bestimmte
Zeichenkette in der Ausgabe vorkommt
• Implementierung z.B. mit RSpec
Then /^I should see "([^"]*)"$/ do |text|
response.should contain(text)
end
36. features/step_definitions/booking_steps.rb
Given /^a travel "([^"]*)" for ([0-9.]*)$/ do |title, price|
Travel.create(:title => title, :price => price.to_f)
end
When /^I press "([^"]*)"$/ do |button|
click_button(button)
end
When /^I fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
fill_in(field, :with => value)
end
Then /^I should see "([^"]*)"$/ do |text|
response.should contain(text)
end
37. Techniken zur Step-
Definition
• Direct Model Access (z.B. mit
ActiveRecord)
• Simulated Browser (Webrat)
• Automated Browser (Selenium)
• RSpec-Befehle
38. Webrat
• Simuliert Browser
• DSL zum steuern des Browsers
• Webrat kann auch ohne Cucumber
eingesetzt werden (z.B. RSpec, Test::Unit,...)
• Schnell
• kein JavaScript
43. Ohne Tabellen
Scenario: booking a Travel
Given a travel “New York” for 2137.40
And a travel “San Francisco” for 2137.40
And a travel “Las Vegas” for 1134.40
And a travel “Dubai” for 3135.40
And a travel “London” for 637.40
And a travel “Berlin” for 337.40
And a travel “Hamburg” for 437.40
And a travel “München” for 1137.40
...
44. Mit Tabellen
Scenario: booking a Travel
Given the following travels
| title | price |
| New York | 2137.40 |
| San Francisco | 2137.40 |
| Las Vegas | 1134.40 |
| Dubai | 3135.40 |
| London | 637.40 |
| Berlin | 337.40 |
| Hamburg | 437.40 |
| München | 1137.40 |
45. Step Definition
Given /^the following travels$/ do |travels|
Travel.create(travels.hashes)
end
travels.class == Cucumber::Ast::Table
travels.hashes ==
[
{:title => “New York”, :price => 2137.40},
{:title => “San Francisco”, :price => 2137.40},
]
47. Ohne Background
Scenario: booking a Travel
Given a travel “New York” for 2137.40
And a travel “San Francisco” for 2137.40
And a travel “Las Vegas” for 1134.40
....
Scenario: booking a Travel for less than 2000
Given a travel “New York” for 2137.40
And a travel “San Francisco” for 2137.40
And a travel “Las Vegas” for 1134.40
....
49. Mit Background
Background:
Given the following travels
| title | price |
| New York | 2137.40 |
| San Francisco | 2137.40 |
...
Scenario: booking a Travel
...
Scenario: booking a Travel for less than 2000
...
50. Step Definition
Given /^the following travels$/ do |travels|
Travel.create(travels.hashes)
end
travels.class == Cucumber::Ast::Table
travels.hashes ==
[
{:title => “New York”, :price => 2137.40},
{:title => “San Francisco”, :price => 2137.40},
]
52. Ohne Scenario Outline
Scenario: login with correct user/password
Given a User “hans” with password “geheim”
When I visit the login-page
And I fill in “username” with “hans”
And I fill in “password” with “geheim”
Then I should see “Login erfolgreich”
Scenario: login with wrong password
Given a User “hans” with password “geheim”
When I visit the login-page
And I fill in “username” with “hans”
And I fill in “password” with “blub”
Then I should see “Login fehlgeschlagen”
54. Mit Scenario Outline
Scenario Outline: login
Given a User “hans” with password “geheim”
When I visit the login-page
And I fill in “username” with <username>
And I fill in “password” with <password>
Then I should see <response>
Examples:
| username | password | response |
| hans | geheim | Login erfolgreich |
| hans | blub | Login fehlgeschlagen |
56. @iteration2
Scenario: booking a Travel
Given a travel “New York” for 2137.40
And a travel “San Francisco” for 2137.40
And a travel “Las Vegas” for 1134.40
....
Scenario: booking a Travel for less than 2000
Given a travel “New York” for 2137.40
And a travel “San Francisco” for 2137.40
And a travel “Las Vegas” for 1134.40
....
57. Aufruf
# Alle Szenarien ausführen mit dem Tag “iteration2”
cucumber - - tags iteration2 features/booking.feature
# Alle Szenarien ausführen ohne den Tag “iteration2”
cucumber - - tags ~iteration2 features/booking.feature
61. Ausführen von Cucumber
Alle Features ausführen (mit rake)
rake features
Alle Features ausführen (ohne rake)
cucumber features # vorher ggf. rake db:test:prepare
Einzelnes Feature ausführen:
cucumber features/booking.feature
Einzelnes Szenario ausführen:
cucumber features/booking.feature:24