Je veux réutiliser certaines étapes de concombre mais ne semble pas trouver la bonne façon.
Je veux écrire une étape comme:
Given /^I login with (.*) credentials$/ |type|
# do stuff with type being one of "invalid" or "valid"
end
Mais alors faites une autre étape comme:
Given /^I login successfully$
# call "Given I login with valid credentials"
end
Donc, en testant l'authentification des utilisateurs, je peux utiliser le premier, mais la plupart des autres endroits, je peux utiliser le dernier, sans avoir à reproduire le code.
Existe-t-il un moyen d'appeler cette autre étape, ou dois-je simplement mettre la logique dans une méthode d'assistance, et appeler ladite méthode à partir de chaque tâche (essentiellement une refactorisation d'extraction de méthode, qui, après avoir lu ma question, me fait croire que c'est en fait la meilleure façon en tous cas)?
UPDATE : La méthode décrite ci-dessous est obsolète. La façon recommandée d'appeler une étape à partir d'une autre étape ressemble maintenant à ceci:
Given /^I login successfully$/
step "I login with valid credentials"
end
Ancienne méthode obsolète (pour référence):
Vous pouvez appeler des étapes à partir d'autres étapes comme celle-ci:
Given /^I login successfully$/
Given "I login with valid credentials"
Then "I should be logged in"
end
Si tous les scénarios d'une fonctionnalité l'exigent (ou d'autres étapes), vous pouvez également ajouter un arrière-plan à chaque fonctionnalité, avec les étapes courantes, comme suit:
Background:
Given I log in with valid credentials
Scenario: Change my password
Given I am on the account page
Notez que la méthode d'appel des étapes dans les étapes a changé dans les versions récentes de concombre, ce que vous verrez si vous obtenez une erreur comme "AVERTISSEMENT: l'utilisation de" Donné/Quand/Alors "dans les définitions d'étape est déconseillée, utilisez" étape "pour appelez d'autres étapes à la place: /path/to/step_definitions/foo_steps.rb: 631: dans `block in '". Voir le wiki concombre pour plus de détails.
L'essentiel de la modification est que vous devez maintenant utiliser les méthodes step
ou steps
.
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
L'appel d'étapes à partir de définitions d'étapes est une mauvaise pratique et présente certains inconvénients :
Aslak Hellesøy recommande pour extraire les actions populaires vers World au lieu de réutiliser les étapes. Il isole ces actions en un seul endroit, rend ce code plus facile à trouver. Vous pouvez également extraire le code des classes ou modules Ruby habituels).
#/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
Voici une discussion utile sur le sujet dans la liste de diffusion Cucumber - link
Mieux vaut envelopper vos pas en% {} plutôt qu'en guillemets. Ensuite, vous n'avez pas besoin d'échapper aux guillemets doubles que vous devrez utiliser fréquemment .:
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
Réutilisez les mots-clés dans le fichier de fonctionnalité qui permettront la réutilisation du code.
Il est fortement déconseillé d'appeler les échelons dans les échelons.
J'écrirais mon fichier de fonctionnalités de cette façon,
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 |
Dans ma définition d'étape, (c'est 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
}
}
De cette façon, il y a beaucoup de réutilisation de code. Vos mêmes données et puis gère les scénarios valides et non valides. Dans le même temps, votre fichier de fonctionnalités a du sens pour les lecteurs.