einführung in cucumber mit rails
Post on 15-May-2015
4.085 Views
Preview:
DESCRIPTION
TRANSCRIPT
CucumberHussein Morsy und Tanja Otto
30.06.2009 Heinrich-Heine-Universität Düsseldorf
Rails User Group Düsseldorf
Ü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
Wer setzt Cucumber in seinen Projekten ein?
Aufbau
• Philosophie
• Cucumber Features erstellen
• Cucumber Features automatisieren
• Tabellen, Outlines und weitere Helferleins
• Cucumber installieren und konfigurieren
• Demo
Philosophie
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
Units
Model Model Model Model
Controller Controller Controller
Views Views Views Views
Model
TDD-Tools
• Unit-Test-Frameworks in Ruby
• Test::Unit
• Shoulda
• RSpec
• ...
Ziel von BDD
writing software that matters
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
Outside-In
Model Model Model Model
Controller Controller Controller
Views Views Views Views
Model
Cucumber
Cucumber
Applikation
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
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, ... )
Features
Aufbau von Features
• Titel & Kurzbeschreibung
• Ein oder mehrere Szenarien (die die Akzeptanzkriterien darstellen)
Titel und Kurzbeschreibung
Feature: Booking As a Customer I want to book a travel So that I can spend my holidays with Sales-Lentz
Scenario:....
Feature: Booking As a .... (Role) I want to .... (Action) So that ... (Buisniss value/ Outcome)
Szenarien
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"
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"
Aufbau eines Szenarios
• Titel (Scenario:)
• Steps
• Vorbedingungen (Given)
• Aktionen (When)
• Erwartungen (Then)
Features auf Deutsch
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
Automatisieren von Features
Ziel
Automatisiertes ausführen der Features
auf der Applikation
wie in einem Webbrowser
Step-Definition
Ruby Code, der die Steps in den Szenarien ausführbar macht
Given a travel “Rhein in Flammen” for 137.40
Step
Given-Step mit Definition
Given /̂ a travel "([̂ \"]*)" for ([0-9.]*)$/ do |title, price| Travel.create(:title => title, :price => price.to_f)end
Step-Definition
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
When-Step mit Definition
When /̂ I press "([̂ \"]*)"$/ do |button| click_button(button)end
When I press “buchen”
Step
Step-Definition
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
Then-Step mit Definition
Then /̂ I should see "([̂ \"]*)"$/ do |text| response.should contain(text)end
Then I should see "Ihre Buchung"
Step
Step-Definition
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
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
features/step_definitions/booking_steps.rb
Techniken zur Step-Definition
• Direct Model Access (z.B. mit ActiveRecord)
• Simulated Browser (Webrat)
• Automated Browser (Selenium)
• RSpec-Befehle
Webrat
• Simuliert Browser
• DSL zum steuern des Browsers
• Webrat kann auch ohne Cucumber eingesetzt werden (z.B. RSpec, Test::Unit,...)
• Schnell
• kein JavaScript
visit home_path
click_link "Sign up"
fill_in "Email", :with => "good@example.com"
select "Free account"
click_button "Register"
Selenium
• Wird im Firefox-Browser ausgeführt
• Führt JavaScript aus
• Langsam
Tabellen, Outlines und weitere Helferleins
Tabellen
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 . . .
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 |
Step Definition
Given /̂ the following travels$/ do |travels| Travel.create(travels.hashes)end
travels.class == Cucumber::Ast::Tabletravels.hashes ==[ {:title => “New York”, :price => 2137.40}, {:title => “San Francisco”, :price => 2137.40},]
Background
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 ....
Don’t repeat yourself
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...
Step Definition
Given /̂ the following travels$/ do |travels| Travel.create(travels.hashes)end
travels.class == Cucumber::Ast::Tabletravels.hashes ==[ {:title => “New York”, :price => 2137.40}, {:title => “San Francisco”, :price => 2137.40},]
Scenario Outlines
Ohne Scenario OutlineScenario: 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”
Don’t repeat yourself
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 |
Tags
@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 ....
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
Cucumber installieren und konfigurieren
Installation
[sudo] gem install rspec rspec-rails cucumber webrat
Gems installieren:
script/generate cucumber
Verzeichnisse und Konfigurationsdateien generieren
Ausführen von Cucumber
rake features
Alle Features ausführen (mit rake)
cucumber features/booking.feature
Einzelnes Feature ausführen:
cucumber features/booking.feature:24
Einzelnes Szenario ausführen:
cucumber features # vorher ggf. rake db:test:prepare
Alle Features ausführen (ohne rake)
Demo
Links
Sites
• Homepage: http://cukes.info/
• Linksammlung: http://delicious.com/mucki/cucumber
Session & Screencasts
• Railscast.com
• http://railscasts.com/episodes/156-webrat
• http://railscasts.com/episodes/155-beginning-with-cucumber
• http://railscasts.com/episodes/159-more-on-cucumber
• ...
Literatur
The RSpec Book: http://www.pragprog.com
Download der Präsentationhttp://devteam.sales-lentz.lu
Follow us on twitter:
https://twitter.com/HusseinMorsy
https://twitter.com/ajnato
top related