限制黄瓜步骤或步骤文件到特定的功能或标签

7
我已经为我们的Web应用程序编写了一个模态幻灯片,它为文档集合提供导航,并公开这些文档的各种元数据。
这是应用程序的一个大组件,具有深奥的要求,因此我认为其核心场景(作为验收标准给我的)既多样化又内部一致是合理的。
为避免针对我们众多场景进行新步骤的编写,我使用了一个帮助程序,该程序将可读性强的术语(例如“文档标题”)翻译成选择器。你可以参考这里了解更多。
module SelectorsHelper
  def selector_for(term)
    case term
    # Lightbox / modal / fancybox
    when 'lightbox'
        '#fancybox-inner'
    when 'close button'
        '.document-viewer__tools__close'

除了以下几个通用的步骤定义,还有其他一些特定于 IT 技术的定义:

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

无论是像上面那样处理非常通用的概念,还是涉及到在一组特征中重复出现的模式等更具体的抽象概念,问题在于它们可能会对其他深奥的特征造成破坏,而这些特征可能有更具体的步骤来解析它们。我看过的每个Cucumber示例都有一个步骤定义文件,其文件名与特定特征文件存在过程关系,我的假设是,在这些情况下,该步骤定义文件只会被调用以解析与其相关的特征中的场景:

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

但事实并非如此——我很难接受黄瓜试图将每种步骤定义模式应用于每个场景。如果这些测试要有任何价值,它们将变得更加数量众多,引入新的概念,并且不需要不断重写就能保持相关性。我希望能够限制我的步骤范围,防止它们干扰不是为其编写的功能,但我不知道该怎么做。以下概念解决方案值得考虑:
  • 使用背景或场景@tags,仅为具有这些标签的场景调用步骤
  • 将步骤定义嵌套在某种包装助手或元步骤定义中,该定义由错误的背景给出时调用
我不熟悉Ruby,而且黄瓜似乎非常简单,所以我感到无从下手,一方面有无限的潜力,另一方面没有预先确定的实现。你有什么想法?
1个回答

4
根据我的经验,过于泛化的步骤会导致难以维护的自动化代码库。如果可能的话,要努力取得平衡,只有你才能判断这种平衡点在哪里。你不希望步骤定义过于重复,但也不想要一个超级泛化的噩梦来调试。
虽然有解决方法可以获取标签列表,但请千万不要这样做。这是令人厌恶、奇怪且不符合 cucumber 的使用意图。
作为一种解决方法,在你的 step_definitions 中,你可以使用环绕步骤来从场景中获取标签名称 -
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

我认为使用这个功能是极其不好的想法。最好拥有稍微重复但易于理解和调试的步骤定义,而不是一个超级通用的步骤定义来统治它们所有!

编辑-重新阅读您的问题和博客文章后,我认为这并不真正回答您的问题。然而,我相当确定您正在尝试做一些非cucumber风格的事情。


我认为我的问题在寻找一个过于具体的解决方案来应对一个非常普遍的困境。这是我所能期望到的最好的问题。你的建议 - 不是黄瓜的预期使用方式 - 很有道理。如果我将来再次使用黄瓜,我会遵循那个建议! - Barney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接