将黄瓜步骤或步骤文件限制为指定的功能或标记

时间:2013-07-31 14:50:58

标签: ruby testing module cucumber bdd

我为我们的网络应用程序编写了一个模态幻灯片,它为文档集提供了导航,并为这些文档公开了各种元数据。

这是具有深奥要求的应用程序的一个重要组成部分,所以我认为它的核心场景(作为验收标准给我)应该是众多但内部一致的。

为避免为我们的众多场景中的每个场景设置新步骤,我调整了a helper,将document caption等人类可读术语翻译成选择器:

module SelectorsHelper
  def selector_for(term)
    case term
    # Lightbox / modal / fancybox
    when 'lightbox'
        '#fancybox-inner'
    when 'close button'
        '.document-viewer__tools__close'

...以及一些通用步骤定义,例如:

# Generic click action
When(/^I click (?:on )?(?:the |a )'(.*?)'?$/) do |element|
  find(selector_for(element)).click
end

问题是,我是否采用非常通用的概念,如上述或更具体的抽象涉及在一组特征中重现的模式,这些问题可能会对其他深奥的特征造成严重破坏,这些特征可能具有更具体的特征解析它们的步骤。我见过的每个Cucumber示例都有步骤定义文件,其文件名与特定的特征文件具有程序关系,我的假设是在这些情况下,只会调用该步骤定义文件来解析其相关特征中的场景: / p>

+ features
| + step_definitions
| | + global_steps.rb
| | + modal_steps.rb
| | + login_steps.rb
| + modal.feature
| + login.feature

但事实并非如此 - 而且我正在努力让自己屈服于Cucumber尝试将每个步骤定义模式应用于每个场景的概念。如果这些测试具有任何优点,它们将会变得更多,引入新的概念,并保持相关性而无需不断重写。我希望能够限制我的步骤范围,以阻止他们干扰他们没有编写的功能,但不知道如何。我想到了以下概念解决方案:

  • 使用背景或方案@tags并仅针对包含这些标记的方案调用步骤
  • 在某种包装帮助器或元步骤定义中嵌套步骤定义,这种定义由给出的错误背景调用

我不熟悉Ruby和Cucumber似乎非常薄,所以一方面我被无限的潜力所震撼,另一方面没有预先确定的实施。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

根据我的经验,过于通用的步骤会导致难以维护的自动化代码库。如果可能的话,尽量在这里寻求平衡,只有你可以判断这种平衡的位置。您不希望过度重复的步骤定义,但您不希望调试超级通用的恶梦。

可以使用变通方法来获取标签列表,但请不要这样做。这很奇怪,而不是如何使用黄瓜。

作为step_definitions中的变通方法,您可以使用around步骤从方案中获取标记名称列表 -

Around do |scenario, block|
  begin
    @tag_names = scenario.tags.collect { |tag| tag.name }
    block.call
  ensure
    $tags = nil
  end
end

然后在step_definition主体中检查您要检测的标签是否包含在列表中 -

Given(/^I am testing a step with a "([^"]*)"$/) do |arg|
  if @tag_names.include?('@a_tag')
    puts 'Executing a step definition with tag - @a_tag'
  else
    puts 'Executing a step definition without tag - @a_tag'
  end
end

此功能 -

Feature: Example feature

  @a_tag
  Scenario: Example scenario #1
    Given I am testing a step with a "value"

  Scenario: Example scenario #1
    Given I am testing a step with a "value"

此输出中的结果 -

Feature: Example feature

  @a_tag
  Scenario: Example scenario #1              # features/example.feature:4
    Given I am testing a step with a "value" # features/step_definitions/step_definitions.rb:10
      Executing a step definition with tag - @a_tag

  Scenario: Example scenario #1              # features/example.feature:7
    Given I am testing a step with a "value" # features/step_definitions/step_definitions.rb:10
      Executing a step definition without tag - @a_tag

2 scenarios (2 passed)
2 steps (2 passed)
0m0.004s

我认为使用它是一个非常糟糕的主意。最好有一个稍微重复的步骤定义,这些步骤定义易于遵循和调试,然后有一个超级通用的步骤定义来统治它们!

编辑 - 在重新阅读您的问题和博文后,我认为这不会真正回答您的问题。但是,我相当肯定你正在尝试做一些非黄色的事情