2009-05-27 17 views
94

Ich möchte einige Gurkenschritte wiederverwenden, finde aber nicht den richtigen Weg.Reuse Gurkenschritte

Ich möchte einen Schritt schreiben wie:

Given /^I login with (.*) credentials$/ |type| 
    # do stuff with type being one of "invalid" or "valid" 
end 

Aber dann wie einen weiteren Schritt haben:

Given /^I login successfully$ 
    # call "Given I login with valid credentials" 
end 

So Authentifizierung Testen Benutzer ich den ehemaligen verwenden können, aber die meisten anderen Orten, ich kann letzteres verwenden und muss nicht wirklich neu codieren.

Gibt es eine Möglichkeit, diesen anderen Schritt zu nennen, oder lege ich einfach die Logik in eine Hilfsmethode und rufe diese Methode von jeder Aufgabe (im Grunde eine Methode Extraktion Refactoring, die nach dem Lesen meiner Frage mich glauben lässt eigentlich der beste Weg sowieso)?

+1

Falls jemand verwirrt ist, lässt jeder hier das 'do' aus, um den' do ... end' Block in der Ruby Schrittdefinition zu starten. Es ist in der Tat erforderlich. –

Antwort

98

UPDATE: Die unten beschriebene Methode ist veraltet. Der empfohlene Weg, einen Schritt aus einem anderen Schritt zu nennen sieht nun wie folgt aus:

Given /^I login successfully$/ 
    step "I login with valid credentials" 
end 

Alt, veraltete Methode (Referenz):

Sie Schritte von anderen Schritten wie folgt aufrufen können :

Given /^I login successfully$/ 
    Given "I login with valid credentials" 
    Then "I should be logged in" 
end 

Wenn alle Szenarien innerhalb eines Merkmals dieser (oder anderen Schritte) benötigen, können Sie auch einen Hintergrund zu jedem Feature, mit th hinzufügen e gemeinsame Schritte, etwa so:

Background: 
    Given I log in with valid credentials 

Scenario: Change my password 
    Given I am on the account page 
+4

Noch einfacher ist das Einfügen des Gurken-Codes wie folgt: 'steps% Q {Vorausgesetzt, ich bin eingeloggt}' – BrendanDean

+1

@BrendanDean Wenn diese Antwort akzeptiert wurde, war die Methode 'steps' nicht vorhanden. Siehe meine Antwort unten. – michaeltwofish

+6

dieser Weg ist veraltet – Karan

101

Beachten Sie, dass das Verfahren für die Schritte in Schritten Aufruf in den letzten Versionen von Gurken hat sich geändert, die Sie, wenn Sie einen Fehler wie „WARNING sehen werden: Verwendung von‚Angesichts/Wenn/Dann 'in Step-Definitionen ist veraltet, verwenden Sie' Schritt ', um stattdessen andere Schritte aufzurufen: /path/to/step_definitions/foo_steps.rb: 631: in `block in' ". Einzelheiten finden Sie unter cucumber wiki.

Das Wesentliche der Änderung ist, dass Sie jetzt die Methoden step oder steps verwenden sollten.

When /^I make all my stuff shiny$/ 
    step "I polish my first thing" 
end 

When /^I make all my stuff shiny$/ 
    steps %Q{ 
    When I polish my first thing 
    When I shine my second thing 
    } 
end 
+16

Für was es wert ist, nach mehr Zeit mit Gurke, empfehle ich nicht Schritte in Schritten überhaupt zu verwenden. Probleme sind schwer aufzuspüren und machen die Wartung schwieriger. Verwenden Sie stattdessen Hilfsmethoden. – michaeltwofish

+1

Vielleicht solltest du diesen Kommentar in deine Antwort aufnehmen, da er sehr hoch ist und immer noch Stimmen erhält. Es wird den Leuten helfen, diese Information zu bemerken –

+0

hi @michaeltwofish, gibt es daran 2017 Änderungen? Ich bekomme 'Syntax Fehler, unerwartete TIDENTIFIER, erwartet, dass keyword_end' http://stackoverflow.com/questions/43319331/calabash-android-high-level-step-definition-syntax-error-unexpected-titidentific – ericn

8

Am besten wickeln Sie Ihre Schritte in% {} und nicht in Anführungszeichen. Dann brauchen Sie nicht doppelte Anführungszeichen zu entkommen, die Sie häufig verwenden müssen, werden .:

Given /^I login successfully$ 
    step %{I login with valid credentials} 
end 

Given /^I login with (.*) credentials$/ |type| 
    # do stuff with type being one of "invalid" or "valid" 
end 
+5

Dies sollte haben war ein Kommentar statt einer Antwort. – Kelvin

40

Schritte von Schritt Definitionen Aufruf eine schlechte Praxis und hat some disadvantages:

  1. Wenn Szenario fehlschlagen und es gibt verschachtelte Schrittaufrufe, Sie erhalten nur die letzte aufgerufene Schrittdefinition in der Stapelüberwachung.Es kann schwierig sein zu finden, von dem Ort, die letzten stepdef
  2. Anruf genannt wurde stepdef manchmal zu finden ist schwieriger und liest als Ruby-Methode
  3. Ruby-Methoden geben Ihnen mehr Energie als Schritte von Schritt defs Aufruf

Aslak Hellesøy recommends, um beliebte Aktionen zu World statt Wiederverwendungsschritte zu extrahieren. Es isoliert diese Aktionen an einem Ort, macht diesen Code leichter zu finden. Sie können auch Code in normale Ruby-Klassen oder Module extrahieren.

#/support/world_extensions.rb 
module KnowsUser 
    def login 
    visit('/login') 
    fill_in('User name', with: user.name) 
    fill_in('Password', with: user.password) 
    click_button('Log in') 
    end 

    def user 
    @user ||= User.create!(:name => 'Aslak', :password => 'xyz') 
    end 
end 
World(KnowsUser) 

#/step_definitions/authentication_steps.rb 
When /^I login$/ do 
    login 
end 

Given /^a logged in user$/ do 
    login 
end 

Hier ist eine nützliche Diskussion über das Thema in Gurken-Mailingliste - link

+2

Ich glaube, dieser Ansatz ist viel besser als Aufruf von Schritt oder Schritte Funktionen aus den gleichen Gründen wie oben erwähnt. – pisaruk

+2

Dies hat einen weiteren Vorteil. Mit Idea (oder Rubymine) können Sie leicht zu Funktionsdefinitionen springen, aber nicht zu den Schritten in Schritten% {...}. – slipset

+0

auch dieses Setup folgt DRY-Prinzip – Sorcerer86pt

1

Reuse Keywords in Feature-Datei, die Wiederverwendbarkeit von Code zur Verfügung stellt.

Es wird NICHT empfohlen, Step Defs innerhalb von Step Defs aufzurufen.

Ich würde meine Funktion Datei auf diese Weise,

Scenario Outline: To check login functionality 
    Given I login with "<username>" and "<password>" 
    Then I "<may or may not>" login successfully 

Examples: 
    |username|password|may or may not| 
    |paul |123$ |may   | 
    |dave |1111 |may not  | 

In meinem Schritt Definition schreiben, (Dies ist Java)

@Given(I login with \"([^\"]*)\" and \"([^\"]*)\"$) 
public void I_login_with_and(String username, String password){ 

    //login with username and password 

} 

@Then(I \"([^\"]*)\" login successfully$) 
public void I_login_successully_if(String validity){ 

    if(validity.equals("may")){ 
     //assert for valid login 
    } 
    else 
    if(validity.equals("may not")){ 
     //assert for invalid login 
    } 
} 

Auf diese Weise gibt es eine Menge Code Wiederverwertbarkeit. Ihre gleichen Given und Then behandelt sowohl gültige als auch ungültige Szenarien. Gleichzeitig ist Ihre Feature-Datei für die Leser sinnvoll.

Verwandte Themen