einführung in cucumber mit rails
DESCRIPTION
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 gehaltenTRANSCRIPT
![Page 1: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/1.jpg)
CucumberHussein Morsy und Tanja Otto
30.06.2009 Heinrich-Heine-Universität Düsseldorf
Rails User Group Düsseldorf
![Page 2: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/2.jpg)
Ü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
![Page 3: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/3.jpg)
Wer setzt Cucumber in seinen Projekten ein?
![Page 4: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/4.jpg)
Aufbau
• Philosophie
• Cucumber Features erstellen
• Cucumber Features automatisieren
• Tabellen, Outlines und weitere Helferleins
• Cucumber installieren und konfigurieren
• Demo
![Page 5: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/5.jpg)
Philosophie
![Page 6: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/6.jpg)
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
![Page 7: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/7.jpg)
Units
Model Model Model Model
Controller Controller Controller
Views Views Views Views
Model
![Page 8: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/8.jpg)
TDD-Tools
• Unit-Test-Frameworks in Ruby
• Test::Unit
• Shoulda
• RSpec
• ...
![Page 9: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/9.jpg)
Ziel von BDD
writing software that matters
![Page 10: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/10.jpg)
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
![Page 11: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/11.jpg)
Outside-In
Model Model Model Model
Controller Controller Controller
Views Views Views Views
Model
![Page 12: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/12.jpg)
Cucumber
![Page 13: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/13.jpg)
Cucumber
Applikation
![Page 14: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/14.jpg)
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
![Page 15: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/15.jpg)
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, ... )
![Page 16: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/16.jpg)
Features
![Page 17: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/17.jpg)
Aufbau von Features
• Titel & Kurzbeschreibung
• Ein oder mehrere Szenarien (die die Akzeptanzkriterien darstellen)
![Page 18: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/18.jpg)
Titel und Kurzbeschreibung
![Page 19: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/19.jpg)
Feature: Booking As a Customer I want to book a travel So that I can spend my holidays with Sales-Lentz
Scenario:....
![Page 20: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/20.jpg)
Feature: Booking As a .... (Role) I want to .... (Action) So that ... (Buisniss value/ Outcome)
![Page 21: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/21.jpg)
Szenarien
![Page 22: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/22.jpg)
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 "[email protected]" 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 "[email protected]" Then I should see "137,40 EUR" Then I should not see "Ausgebucht"
![Page 23: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/23.jpg)
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 "[email protected]" 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 "[email protected]" And I should see "137,40 EUR" But I should not see "Ausgebucht"
![Page 24: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/24.jpg)
Aufbau eines Szenarios
• Titel (Scenario:)
• Steps
• Vorbedingungen (Given)
• Aktionen (When)
• Erwartungen (Then)
![Page 25: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/25.jpg)
Features auf Deutsch
![Page 26: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/26.jpg)
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
![Page 27: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/27.jpg)
Automatisieren von Features
![Page 28: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/28.jpg)
Ziel
Automatisiertes ausführen der Features
auf der Applikation
wie in einem Webbrowser
![Page 29: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/29.jpg)
Step-Definition
Ruby Code, der die Steps in den Szenarien ausführbar macht
![Page 30: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/30.jpg)
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
![Page 31: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/31.jpg)
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
![Page 32: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/32.jpg)
When-Step mit Definition
When /̂ I press "([̂ \"]*)"$/ do |button| click_button(button)end
When I press “buchen”
Step
Step-Definition
![Page 33: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/33.jpg)
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
![Page 34: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/34.jpg)
Then-Step mit Definition
Then /̂ I should see "([̂ \"]*)"$/ do |text| response.should contain(text)end
Then I should see "Ihre Buchung"
Step
Step-Definition
![Page 35: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/35.jpg)
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
![Page 36: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/36.jpg)
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
![Page 37: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/37.jpg)
Techniken zur Step-Definition
• Direct Model Access (z.B. mit ActiveRecord)
• Simulated Browser (Webrat)
• Automated Browser (Selenium)
• RSpec-Befehle
![Page 38: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/38.jpg)
Webrat
• Simuliert Browser
• DSL zum steuern des Browsers
• Webrat kann auch ohne Cucumber eingesetzt werden (z.B. RSpec, Test::Unit,...)
• Schnell
• kein JavaScript
![Page 39: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/39.jpg)
visit home_path
click_link "Sign up"
fill_in "Email", :with => "[email protected]"
select "Free account"
click_button "Register"
![Page 40: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/40.jpg)
Selenium
• Wird im Firefox-Browser ausgeführt
• Führt JavaScript aus
• Langsam
![Page 41: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/41.jpg)
Tabellen, Outlines und weitere Helferleins
![Page 42: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/42.jpg)
Tabellen
![Page 43: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/43.jpg)
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 . . .
![Page 44: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/44.jpg)
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 |
![Page 45: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/45.jpg)
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},]
![Page 46: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/46.jpg)
Background
![Page 47: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/47.jpg)
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 ....
![Page 48: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/48.jpg)
Don’t repeat yourself
![Page 49: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/49.jpg)
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...
![Page 50: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/50.jpg)
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},]
![Page 51: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/51.jpg)
Scenario Outlines
![Page 52: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/52.jpg)
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”
![Page 53: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/53.jpg)
Don’t repeat yourself
![Page 54: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/54.jpg)
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 |
![Page 55: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/55.jpg)
Tags
![Page 56: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/56.jpg)
@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 ....
![Page 57: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/57.jpg)
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
![Page 58: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/58.jpg)
Cucumber installieren und konfigurieren
![Page 59: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/59.jpg)
Installation
[sudo] gem install rspec rspec-rails cucumber webrat
Gems installieren:
script/generate cucumber
Verzeichnisse und Konfigurationsdateien generieren
![Page 60: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/60.jpg)
![Page 61: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/61.jpg)
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)
![Page 62: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/62.jpg)
![Page 63: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/63.jpg)
Demo
![Page 64: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/64.jpg)
Links
![Page 65: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/65.jpg)
Sites
• Homepage: http://cukes.info/
• Linksammlung: http://delicious.com/mucki/cucumber
![Page 66: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/66.jpg)
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
• ...
![Page 67: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/67.jpg)
Literatur
The RSpec Book: http://www.pragprog.com
![Page 68: Einführung in Cucumber mit Rails](https://reader030.vdocuments.site/reader030/viewer/2022013003/5555beddd8b42afe5d8b51bf/html5/thumbnails/68.jpg)
Download der Präsentationhttp://devteam.sales-lentz.lu
Follow us on twitter:
https://twitter.com/HusseinMorsy
https://twitter.com/ajnato