重复使用黄瓜步骤

我想重用一些黄瓜步骤,但似乎无法find正确的方法。

我想写一个像这样的步骤:

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

但是,接下来的另一个步骤是:

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

所以在testing用户身份validation我可以使用前者,但大多数其他地方,我可以使用后者,而不是实际上必须repro代码。

有没有办法调用另一个步骤,或者我只是把逻辑放在一个辅助方法中,然后从每个任务调用这个方法(基本上是一个方法提取重构,在阅读我的问题之后,我相信这实际上是最好的方法无论如何)?

更新 :下面描述的方法已被弃用。 从另一个步骤中调用步骤的build议方式现在看起来像这样:

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

旧的,不推荐的方法(供参考):

您可以通过以下其他步骤调用步骤:

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

如果某个function中的所有场景都需要这个(或其他步骤),则还可以使用常见步骤为每个要素添加一个Background,如下所示:

 Background: Given I log in with valid credentials Scenario: Change my password Given I am on the account page 

请注意,在步骤中调用步骤的方法在黄瓜的最新版本中已经发生了变化,如果您在步骤定义中使用'Given / When / Then'时出现如下错误,请使用'step'请调用其他步骤:/path/to/step_definitions/foo_steps.rb:631:在`block in'“中。 有关详细信息,请参阅黄瓜维基 。

改变的要点是你现在应该使用stepsteps方法。

 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 

从步骤定义调用步骤是一个不好的做法,有一些缺点 :

  1. 如果场景失败,并且嵌套步骤调用,则只会获取堆栈跟踪中最后一个调用的步骤定义。 可能很难find最后一个stepdef被调用的地方
  2. 调用stepdef有时候比ruby方法更难find和阅读
  3. Ruby方法给你比从step defs调用步骤更多的能力

AslakHellesøy build议将stream行的操作提取到世界,而不是重复使用步骤。 它将这些操作隔离在一个地方,使代码更容易find。 您可以将代码提取到常见的Ruby类或模块中。

 #/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 

这里是关于这个主题在Cucumber邮件列表中的一个有用的讨论 – 链接

最好在%{}而不是引号中包装你的步骤。 那么,你不需要经常使用双引号。

 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 

重用function文件中的关键字,它将提供代码的可重用性。

强烈build议在step defs中调用step defs。

我会这样写我的function文件,

 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 | 

在我的步骤定义中,(这是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 } } 

这样就有很多代码可重用性。 您相同的Given和Then处理有效和无效的情况。 同时,您的function文件对读者来说是有意义的。