重复使用黄瓜步骤

Dan*_*tep 103 ruby testing cucumber

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

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

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

但是又有另一个步骤:

Given /^I login successfully$
  # call "Given I login with valid credentials"
end
Run Code Online (Sandbox Code Playgroud)

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

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

mic*_*ish 103

请注意,在最近版本的黄瓜中调用步骤中的步骤的方法已经改变,如果出现"警告:在步骤定义中使用'给定/何时/然后'"这样的错误,您将会看到,请使用'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
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,经过与Cucumber的更多时间之后,我建议不要在步骤中使用步骤.问题难以追查,实际上使维护更加困难.相反,使用辅助方法. (18认同)
  • 也许,你应该把这个评论包括在你的答案中,因为它非常受欢迎,但仍然会收到投票.它将帮助人们注意到这些信息 (2认同)

tom*_*fro 102

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

Given /^I login successfully$/
    step "I login with valid credentials" 
end 
Run Code Online (Sandbox Code Playgroud)

旧的,弃用的方法(供参考):

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

Given /^I login successfully$/
  Given "I login with valid credentials"
  Then "I should be logged in"
end
Run Code Online (Sandbox Code Playgroud)

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

Background:
  Given I log in with valid credentials

Scenario: Change my password
  Given I am on the account page
Run Code Online (Sandbox Code Playgroud)

  • 更容易的是粘贴小黄瓜代码:`steps%Q {鉴于我已登录}` (5认同)

And*_*lov 43

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

  1. 如果场景失败并且存在嵌套的步骤调用,则只会获得堆栈跟踪中最后一次调用的步骤定义.可能很难找到最后一个stepdef被调用的地方
  2. 调用stepdef有时比ruby方法更难找到和读取
  3. Ruby方法比调用步骤defs中的步骤提供更多功能

AslakHellesø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
Run Code Online (Sandbox Code Playgroud)

以下是关于Cucumber邮件列表中主题的有用讨论 - 链接

  • 我确实认为这种方法比调用步骤或步骤函数要好得多,原因与上述相同. (2认同)
  • 这有另一个好处.使用Idea(或Rubymine),您可以轻松跳转到函数定义,但不能跳到步骤%{...}中的步骤. (2认同)
  • 虽然我遇到了重复使用步骤的问题,但我认为这很糟糕.登录只是不同步骤的总和:"访问一些东西","填充一些东西".自然的方式是重用步骤,而不是将每个步骤转换为对函数的调用.IMO,调用步骤内的步骤应该只是改进. (2认同)

Rim*_*ian 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
Run Code Online (Sandbox Code Playgroud)

  • 这应该是评论而不是答案. (5认同)