重复使用黄瓜步骤

时间:2009-05-27 21:20:45

标签: ruby testing cucumber

我想重用一些Cucumber步骤,但似乎无法找到正确的方法。

我想写一个像:

的步骤
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

因此,在测试用户身份验证时,我可以使用前者,但大多数其他地方,我可以使用后者,而不是实际上必须重新编码。

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

5 个答案:

答案 0 :(得分:102)

请注意,在最近版本的黄瓜中,调用步骤中的步骤的方法已经改变,如果出现“警告:在步骤定义中使用'给定/何时/然后'不推荐使用',请使用'步骤'改为调用其他步骤:/path/to/step_definitions/foo_steps.rb:631:在`block in'中 “。有关详细信息,请参阅cucumber wiki

更改的要点是您现在应该使用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 :(得分:101)

更新:不推荐使用下面介绍的方法。从另一个步骤中调用步骤的推荐方法现在看起来像这样:

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

如果功能中的所有方案都需要此(或其他步骤),您还可以使用常用步骤为每个功能添加背景,如下所示:

Background:
  Given I log in with valid credentials

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

答案 2 :(得分:42)

从步骤定义调用步骤是一种不好的做法,并且some disadvantages

  1. 如果方案失败并且存在嵌套的步骤调用,则只会获得堆栈跟踪中最后一次调用的步骤定义。可能很难找到最后一个stepdef叫做哪个地方
  2. 调用stepdef有时比ruby方法更难找到和阅读
  3. Ruby方法比调用步骤defs中的步骤提供更多功能
  4. AslakHellesøyrecommends将常用操作提取到World,而不是重复使用步骤。它将这些操作隔离在一个地方,使这个代码更容易找到。您也可以将代码提取到常用的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邮件列表中主题的有用讨论 - link

答案 3 :(得分:9)

最好用%{}包装您的步骤而不是引号。然后,您不需要转义经常需要使用的双引号。:

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

答案 4 :(得分:1)

在功能文件中重用关键字,这将提供代码可重用性。

强烈建议不要在步骤defs中调用步骤defs。

我会用这种方式编写我的特征文件,

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处理有效和无效的场景。 同时,您的功能文件对读者有意义。