繁体   English   中英

在每个功能之前和之后是否有一个黄瓜钩可以运行

[英]Is there a cucumber hook to run before and after each feature

有没有办法在每个带有特定标签的黄瓜特征之前和之后运行特定的代码块?

由于设置过程非常昂贵,我不想在每个场景之前运行它。

几天前,我与Matt Wynne(黄瓜宝石的核心团队成员之一)进行过交谈,他告诉我黄瓜没有这样的特征(在撰写本文时)。

作为一种解决方法,他建议在每个钩子之前标记整个特征和使用标志,如下所示:

Before('@feature_with_expensive_setup') do
  unless @setup_is_done
    # perform expensive setup code here ..
    @setup_is_done = true
  end
end

LukasMac的答案与@var不兼容。 Ande基于官方的黄瓜维基页面,下面我的例子工作和测试好了,下面的挂钩只执行一次每个功能:

Before('@my_feature_tag') do
  unless $dts_test_preparation_done
    # expensive setup in my case setup lots of database tables for test
    $dts_test_preparation_done = true
  end
end

特色挂钩之前和之后的黄瓜

使用信息

由于红宝石黄瓜没有提供在特征之前和之后创建钩子的选项,因此提出了一种临时解决方案。

要指定与要素相关的挂钩,方法名称必须采用以下格式:

before_feature_ [格式化功能名称] after_feature_ [格式化功能名称]

格式化的要素名称是特征文件中“要素:”行中的文本,其格式为:

(i)所有字符小写; (ii)所有空格均以下划线代替; (iii)删除所有特殊字符

在匹配此约定的方法中,可以使用场景挂钩指定代码。

技术信息

在LukasMac和Gob00st的解决方案的基础上,我为我当前的客户实施了以下变通方法。

这些方法在一个名为AAA_special_hooks的hooks子目录中,位于该目录(唯一文件)中的special_hooks.rb文件中,这是因为所有其他条件相同,钩子将按照它们在项目结构中出现的顺序运行,这样此处创建的挂钩在其他子目录或挂钩基目录中指定的任何方案挂钩之前运行。

下面附录中的代码是vanilla,据我所知它可以适用于所有人。

before钩子的运行原则是设置一个全局标志,以确保钩子只为一个特征运行一次(根据LukasMac和Gob00st)。 由于两个原因,该原则已经扩展到抽象钩子,首先是简化钩子的规范,并且与后钩子实现具有一致性。

挂钩用于确定自上次方案执行以来功能是否已更改。 如果是这样,在当前特征发生任何事件之前,将对前一特征运行后钩子。 显然,该漏洞可能是新功能实际上已经在之前的挂钩运行之前启动,但我无法看到这可能会导致任何问题。 但是最终的特性不能以这种方式运行后钩子,这就是在at_exit方法中重新实现该代码的原因。

附录 - special_hooks.rb代码

def get_formatted_name(feature_name)
  formatted_name = feature_name.downcase.gsub(' ', '_')
  %w[@ ' , . / ! " £ $ % ^ & * ( ) { } [ ] ; : # ~ ? < > \] + = - ` ¬ |].each { |char| formatted_name.gsub! char, '' }
  formatted_name
end

Before do |scenario|
  $completed_before_hooks ||= []
  $feature_name ||= scenario.feature.name
  unless $feature_name == scenario.feature.name
    # run after hook for previous feature
    begin
      send "after_feature_#{get_formatted_name $feature_name}"
    rescue NoMethodError
    end
  end

  #run before hook for current feature if not already done
  begin
    formatted_name = get_formatted_name scenario.feature.name
    unless $completed_before_hooks.include? formatted_name
      $completed_before_hooks << formatted_name
      send "before_feature_#{formatted_name}"
    end
  rescue NoMethodError
  end

  $feature_name = scenario.feature.name
end

at_exit do
  # don't run final hook if error raised that was not handled
  unless $! && $!.status > 1
    puts 'EXECUTING FINAL AFTER HOOK... PLEASE WAIT'
    begin
      send "after_feature_#{get_formatted_name $feature_name}"
    rescue NoMethodError
    end
    puts 'FINAL AFTER HOOK COMPLETED'
  end
end

黄瓜的钩子在这个维基页面中描述它显示了你可以拥有的前后挂钩。

从该页面获取的是此示例:

如果执行时间超过0.5秒,以下示例将导致使用@fast标记的方案失败:

Around('@fast') do |scenario, block|
  Timeout.timeout(0.5) do
    block.call
  end
end

可以通过使用标记@ExecuteBeforeFeature标记特征的第一个场景以及标记为@ExecuteAfterFeature的最后场景,然后将标记的Before和After钩子写成如下来实现对BeforeFeature / AfterFeature挂钩的模拟:

Before('@ExecuteBeforeFeature') do
  #code in this method will be executed only before the first scenario or before the feature if only the first scenario is tagged for this hook.
end

After('@ExecuteAfterFeature') do
  #code in this method will be executed only after the last scenario or after the feature if only the last scenario is tagged for this hook.
end

第一个答案的修改对我来说只用单引号

    Before('@feature_with_expensive_setup') do
      unless '@setup_is_done'
        # perform expensive setup code here ..
        @setup_is_done = true
      end
    end

您可以使用 at_exit 实现 after 功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM