104

我想重用一些 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

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

有没有办法调用其他步骤,或者我只是将逻辑放在辅助方法中,然后从每个任务中调用所述方法(基本上是方法提取重构,在阅读我的问题后,我相信这实际上是最好的方法反正)?

4

5 回答 5

103

请注意,在最新版本的 cucumber 中,在步骤中调用步骤的方法已更改,如果您收到类似“警告:在步骤定义中使用 'Given/When/Then' 已弃用,请使用 'step'改为调用其他步骤:/path/to/step_definitions/foo_steps.rb:631:in `block in '"。有关详细信息,请参阅黄瓜 wiki

更改的要点是您现在应该使用steporsteps方法。

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
于 2011-12-06T05:24:59.653 回答
102

更新:下面描述的方法已被弃用。从另一个步骤中调用一个步骤的推荐方法现在如下所示:

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
于 2009-05-28T11:05:55.280 回答
43

从步骤定义中调用步骤是一种不好的做法,并且有一些缺点

  1. 如果场景将失败并且存在嵌套的步骤调用,您将仅获得堆栈跟踪中最后调用的步骤定义。可能很难找到最后一个 stepdef 是从哪个地方调用的
  2. 调用 stepdef 有时比 ruby​​ 方法更难找到和阅读
  3. Ruby 方法比从 step defs 调用步骤更强大

Aslak Hellesøy建议将流行动作提取到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 邮件列表中有关该主题的有用讨论 -链接

于 2012-03-02T20:01:36.303 回答
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
于 2012-02-21T03:22:55.717 回答
1

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

强烈不建议在 step defs 中调用 step 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 and Then 处理有效和无效的场景。同时,您的功能文件对读者有意义。

于 2013-05-30T22:29:13.740 回答