Ruby ist eine der beliebtesten Sprachen im Internet. Wir führen hier eine Session zu Nettuts + durch, die Sie in Ruby einführt, sowie die großartigen Frameworks und Tools, die mit der Ruby-Entwicklung einhergehen. In dieser Episode erfahren Sie, wie Sie Ihre Sinatra-Apps mit Cucumber, Capybara und Rspec testen.
Im vorherigen Tutorial dieser Serie haben wir uns mit Rspec befasst und wie Sie damit testgetriebene Entwicklung durchführen können. Ich erwähnte, dass wir uns in der nächsten Episode mit Rspec beschäftigen würden, um Web-Apps zu testen. Einige Kommentatoren erwähnten jedoch, dass sie daran interessiert wären, mit Cucumber getestet zu werden. Daher testen wir stattdessen eine sehr einfache Web-App. Eigentlich verwenden wir einen Teil von Rspec, um die gleiche Matchersyntax zu erhalten, wie Sie es beim letzten Mal gesehen haben, aber der eigentliche Testaufbau ist in Cucumber.
Wir werden eine unglaublich einfache Sinatra-App zum Testen erstellen. Als Erstes erstellen wir einen Projektordner und werfen diesen in ein Gemfile:
Was? Du weißt es nicht
Gemfile
s? Raus unter diesem Rock und hol dir Episode 8 nach
quelle: rubygems edelstein "sinatra" edelstein "schrotflinte" edelstein "gurke" edelstein "capybara" edelstein "rspec"
Nun laufe Bundle installieren
in diesem Verzeichnis. Mit den Edelsteinen sind wir bereit! (Falls Sie RVM verwenden, können Sie diese Edelsteine optional nur für dieses Projekt installieren, indem Sie sie ausführen rvm --rvmrc --create 1.9.2@cucumber_example
; Führen Sie das vorher aus Bundle installieren
)
Öffnen Sie also eine Datei mit dem Namen myapp.rb
; hier ist unsere super einfache app; Es simuliert lediglich eine Website, auf der Sie sich möglicherweise für einen Newsletter anmelden können.
erfordern "sinatra / base" Klasse MyApp < Sinatra::Base get "/" do erb :index end post "/thankyou" do @name = params["name"] @email = params["email"] erb :thankyou end get "/form" do erb :form end end
Wenn Sie sich mit Sinatra nicht auskennen, sollten Sie sich Dan Harpers ausgezeichnete Sessions mit Sinatra anhören. Das bringt Sie in kürzester Zeit mit den Grundlagen zum Laufen.
Wenn Sie mit Sinatra vertraut sind, werden Sie feststellen, dass wir hier drei Pfade erstellen. Auf der Startseite ('/') rendern wir nur das index.erb
Vorlage (mehr zu den Vorlagen in einer Minute). Wenn wir eine Post-Anfrage an den Pfad bekommen /Danke dir
, Wir nehmen die Werte der Name
und Email
Parameter und weisen sie Instanzvariablen zu. Instanzvariablen sind in jeder Vorlage, die wir rendern, verfügbar danke.erb
. Endlich um /bilden
, wir machen das form.erb
Vorlage.
Nun lassen Sie uns diese Vorlagen erstellen. Sinatra sucht nach Vorlagen in einem Ordner "Views", also legen wir sie dort ab. Wie du gesehen hast myapp.rb
, Wir verwenden ERB zum Rendern der Vorlagen, daher handelt es sich natürlich um ERB-Vorlagen. Wenn wir eine haben layout.erb
Vorlage, es werden alle unsere anderen Vorlagen verpackt. Also, lass uns das tun:
DIE APP DIE APP
<%= yield %>
Dieser Anruf an Ausbeute
Dort werden die anderen Vorlagen eingefügt. Und diese anderen Vorlagen sind ziemlich einfach:
Dies ist die Startseite
Melden Sie sich für unseren Newsletter an!
Hallo, <%= @name %>. Sie erhalten jetzt unsere E-Mail an <%= @email %>
Also gibt es unsere App. Um es manuell zu testen, können Sie dies in ein einfügen config.ru
Datei:
erfordern "./myapp", um MyApp auszuführen
Und dann renn Schrotflinte
im Terminal. Dies startet einen Webserver, wahrscheinlich auf Port 9393. Sie können jetzt unsere Web-App testen und testen. Aber wir wollen dieses Testen automatisieren, richtig? Machen wir das!
Gurke versteht sich als "verhaltensorientierte Entwicklung mit Eleganz und Freude". Während mir die Freude ein bisschen weit hergeholt erscheint, denke ich, dass wir beide dieser Eleganz zustimmen werden. Nun, Cucumber hat es.
Da die verhaltensorientierte Entwicklung zum Teil dazu dient, die Anforderungen des Kunden zu verstehen, bevor Sie mit dem Programmieren beginnen, zielt Cucumber darauf ab, die Tests für Kunden lesbar zu machen (AKA, Nichtprogrammierer). Sie werden hier also sehen, dass alle Ihre Tests in scheinbar reinem Text (es ist eigentlich Gherkin) geschrieben ist..
Denken Sie daran, wie wir mit Rspec separate Spec-Dateien haben, um die verschiedenen Funktionalitäten zu beschreiben? In der Gurkensprache sind dies Features, und sie gehören alle zu "Features". Mappe. Erstellen Sie in diesem Ordner zwei weitere Ordner namens "Support". und? step_definitions.?
In der? Unterstützung? Ordner öffnen Sie ein env.rb
. Dieser Code richtet unsere Testumgebung ein. Was wir brauchen:
required_relative "? /? / myapp" erfordern "Capybara" erfordern "Capybara / Gurke" erfordern "rspec". World do Capybara.app = MyApp schließt Capybara :: DSL mit RSpec :: Matchers ein
Dies erfordert die verschiedenen Bibliotheken, die wir benötigen und verwenden umfassen
um ihre Methoden in unsere Umgebung zu laden. Was ist das für ein Capybara, das wir verwenden? Im Grunde ist es die Funktionalität, mit der wir unsere Web-App verwenden können, um sie zu testen. Es ist wichtig zu setzen Capybara.app
zu unserer App. Ich sollte erwähnen, dass, wenn wir dies mit einer Rails-App machen würden, der größte Teil dieses Setups für uns automatisch durchgeführt würde.
(Hinweis: Im Screencast habe ich umfassen RSpec :: Expectations
unnötig; Lass es aus.)
Okay, lass uns ein paar Tests schreiben!
Beginnen wir mit unserer Homepage. Öffne die Datei home_pages.feature
(im Ordner "features") und beginnen Sie damit:
Feature: Viewer besucht die Startseite Um die Seite zu lesen Als Zuschauer möchte ich die Startseite meiner App sehen
Dies ist eine übliche Methode zum Starten einer Feature-Datei. Sieht nicht wirklich Code aus, oder? Nun, es ist Gherkin, eine domänenspezifische Sprache (DSL), mit der Sie das Verhalten von Software beschreiben können, ohne zu beschreiben, wie dieses Verhalten implementiert wird. Was wir bisher geschrieben haben, läuft in keiner Weise, erklärt aber den Zweck der Funktion. Hier ist die allgemeine Struktur:
Um [Ziel] Als [Rolle] möchte ich [Funktion]
Sie müssen dieser Vorlage nicht folgen: Sie können alles einfügen, was Sie möchten. Der Zweck besteht darin, das Merkmal zu beschreiben. Dies scheint jedoch ein allgemeines Muster zu sein.
Als Nächstes wird eine Liste von Szenarien angezeigt, in denen die Funktion beschrieben wird. Hier ist der erste:
Szenario: Startseite anzeigen Gegeben, ich bin auf der Startseite. Dann sollte ich "Dies ist die Startseite" sehen.
Jedes Szenario kann aus bis zu drei Teilen bestehen: Gegeben
s, Wann
s und Dann
s:
Gegeben
Zeilen beschreiben, welche Vorbedingung vorhanden sein sollte.Wann
Zeilen beschreiben die Aktionen, die Sie ausführen.Dann
Zeilen beschreiben das Ergebnis.Es gibt auch Und
Linien, die tun, was auch immer die Linie über ihnen tut. Zum Beispiel:
Gegeben, ich bin auf der Startseite und bin angemeldet. Dann sollte ich "Welcome Back!" Sehen. Und ich sollte "Einstellungen" sehen
In diesem Fall der erste Und
Linie wirkt als a Gegeben
Linie, und die zweite fungiert als Dann
Linie.
Wir werden ein paar sehen Wann
Zeilen in Kürze. Aber jetzt lass uns diesen Test durchführen. Um das zu tun, renne Gurke
im Terminal. Sie werden wahrscheinlich so etwas sehen:
Gurken-Feature-Dateien sind so geschrieben, dass sie für Nicht-Programmierer lesbar sind. Daher müssen Schrittdefinitionen für undefinierte Schritte implementiert werden. Zum Glück gibt uns Cucumber zunächst einige Schnipsel.
Wenn Sie diese Ausschnitte betrachten, können Sie sehen, wie dies funktioniert. Jeder Schritt wird mit einem regulären Ausdruck abgeglichen. Alle angegebenen Werte werden erfasst und als Blockparameter übergeben. Innerhalb des Blocks tun wir alles, was wir als Ergebnis dieses Schrittes erwarten. Dies kann ein Einrichtungscode in sein Gegeben
Schritte, einige Berechnungen oder Aktionen in Wann
Schritte und einen Vergleich in Dann
Schritte.
Cucumber lädt alle Dateien im Ordner "features / step_definitions". für Schritte, also lassen Sie uns? sinatra_steps.rb? Datei und fügen Sie diese beiden Schritte hinzu:
Gegeben / ^ Ich bin auf der Startseite $ / do besuche "/" Ende Dann / ^ sollte ich sehen "([^"] *) "$ / do | text | page.hould_content text end
In diesem kleinen Ausschnitt hier verwenden wir Gurke, Rspec und Capybara. Erstens haben wir die Gurke Gegeben
und Dann
Methodenaufrufe. Zweitens verwenden wir die Capybara-Methoden Besuch
(um eine URL zu besuchen) und has_content?
. Aber Sie sehen den Anruf nicht an has_content?
da wir die RSpec-Matcher geladen haben, können wir unsere Tests so ablesen, wie sie es mit Rspec tun würden. Wenn wir RSpec auslassen wollten, würden wir einfach schreiben page.has_content? Text
.
Wenn du jetzt rennst Gurke
Sie werden sehen, dass unsere Tests bestehen:
Fügen wir zwei weitere Szenarien für unsere Homepage hinzu:
Szenario: Überschrift auf der Startseite finden Gegeben bin ich auf der Homepage. Dann sollte ich "MEIN APP" in der Auswahl "h1" sehen. Szenario: Findet den Link zum Formular Gegeben ich bin auf der Homepage. Dann sollte ich "Registrieren" sehen für unseren Newsletter. " in einem Link
Diese erfordern zwei weitere Dann
Schritte, wie Sie finden, wenn Sie versuchen, dies auszuführen. Fügen Sie diese zu hinzu sinatra_steps.rb
:
Dann / ^ Ich sollte "([^"] *) "im Selector" ([^ "] *)" $ / do | text, Selector | sehen page.should have_selector Auswahl, Inhalt: Textende Dann / ^ Ich sollte "([^"] *) "in einem Link $ / do | text | page.should_link.tould_link.tould_hine_link sehen
Sie sollten in der Lage sein zu erkennen, was diese tun: Der erste sucht nach Text innerhalb eines bestimmten Elements auf der Seite. Die zweite sucht nach einem Link mit dem angegebenen Text (ja, das hätten Sie tun können Dann sollte ich in der Auswahl "a" "Anmelden" sehen.
, aber ich wollte dir eine andere Capybara / Rspec-Methode
Wieder rennen Gurke
; Sie sehen alle unsere Tests bestanden:
Lassen Sie uns jetzt? Features / form_page.feature? Wirf das hier rein:
Feature: Viewer registriert sich für den Newsletter Um den Newsletter zu erhalten Als Benutzer der Website möchte ich mich für den Newsletter anmelden können Szenario: Formularseite anzeigen Gegeben bin ich auf "/ form" Dann sollte ich sehen "Füllen" Hier erhalten Sie unseren Newsletter. " Szenario: Formular ausfüllen Wenn ich auf "/ form" stehe, wenn ich mit "John Doe" "Name" ausfülle und mit "[email protected]" "email" "ausfülle". Und ich klicke auf "Anmelden!" Dann sollte ich sehen "Hallo, John Doe. Sie erhalten neu unseren E-Mail-Newsletter unter [email protected]".
Das erste Szenario hier ist ziemlich einfach, obwohl wir das schreiben müssen Gegeben
Schritt für ist. Sie können wahrscheinlich jetzt herausfinden, wie das geht:
Gegeben / ^ Ich bin auf "([^"] *) "$ / do | Pfad | Besuchspfadende
Der zweite ist etwas tiefer. Zum ersten Mal verwenden wir Wann
Schritte (denken Sie daran, die Und
Schritte, die dem folgen Wann
Schritt sind auch Wann
Schritte). Es ist ziemlich offensichtlich, was diese sind Wann
Schritte sollten tun, aber wie machen wir das im Ruby-Code? Zum Glück hat Capybara ein paar nützliche Methoden, um zu helfen:
Wenn / ^ füge ich "([^"] *) "mit" ([^ "] *)" $ / do | element, text | fill_in Element mit: text end Wenn / ^ klicke ich auf "([^"] *) "$ / do | element | click_on Elementende
Wir benutzen die ergänze
Methode, die den Namen oder das ID-Attribut eines Elements auf der Seite übernimmt. Wir benutzen auch klicke auf
, Klicken Sie auf das Element mit dem angegebenen Text, der angegebenen ID oder dem angegebenen Wert. Es gibt auch die spezifischeren click_link
und klicktaste
. Weitere Informationen finden Sie in der Capybara-Readme-Datei. Stöbern Sie im? DSL? Weitere Informationen zu den Methoden, die Capybara anbietet.
Wenn du rennst Gurke
Jetzt sollten Sie alle Tests bestehen und bestanden haben:
Stellen Sie fest, dass wir hier nur die Benutzeroberfläche testen, nicht den zugrunde liegenden Code. Wenn unser Code Sie wirklich für den Newsletter angemeldet hat, müssen wir auch den Code testen, der den Namen und die E-Mail-Adresse in unserer Datenbank hinzufügt bekomme eigentlich den Newsletter, oder? Das sollte separat getestet werden.
Und das testet Web-Apps mit Matchern von Cucumber, Capybara und Rspec. Wie bereits erwähnt, lesen Sie in den Capybara-Dokumenten nach!