从钩子里面的所有黄瓜步骤的全球访问变量

时间:2016-07-25 14:48:21

标签: ruby cucumber

目前我正在加载像Cucumber Hooks这样的所有YAML文件 - 目的是确保我们不单独编码加载YAML文件。

@all_Yaml_Files = Dir.entries(@projectData_Path).select {|f| !File.directory? f};
@all_Yaml_Files.each do |file_Name|
    file_Full_Path = @projectData_Path + '/' + file_Name
    instance_variable_set("@" + file_Name.split('.')[0], YAML.load_file(file_Full_Path))
end

然而,此代码位于Before Cucumber Hook中。因此,当加载实例变量时,它们不适用于下一个场景。如何让它们只运行一次,然后可用于所有场景和所有功能 - 即全局。目前每次都为场景加载。

Before do
....
end

注意:通过上面的操作,我们可以通过@YAML_FileName变量直接访问YAML_FileName而无需编写代码。这是我的意图。所有excel文件,json文件等都是如此。它们都是从Hooks内部调用的。

1 个答案:

答案 0 :(得分:1)

编辑:添加"快速"溶液

快速解决方案

您现在正在使用类变量(@var);这些都受到一些Cucumber魔法的影响,因此在每个场景之后它们会被清除掉,正如您所注意到的那样。这使它们非常有用,给你一个清洁的平板"同时允许您将某个状态从一个步骤转移到下一个步骤。

这个 只是Ruby,所以你当然可以使用全局ruby变量($var)。这仍然需要您更改现有代码。

如果你想保留你的类变量@var并仍然让它们坚持下去,你可以做钩子来保存和恢复全局变量,即:

Around do |scenario, block|
  @var = $var
  begin
    block.call
  ensure
    $var = @var
  end
end

你想要确保足够早地遇到这个钩子,以便在你可能有任何其他钩子之前触发它。

我不想在任何语言中使用全局变量,因此我尽量不在Cucumber中使用@var$var。相反,我更喜欢以OOP的方式来做...因此:

"清洁"解决方案(PORO)

我使用单例模块来做这些事情:

# support/000_cucu_globals.rb

class CucuGlobals
  include Singleton

  def initialize 
    @somevalue = 'hello world'
    ...
  end

  attr_reader :somevalue
end

其他地方:

puts CucuGlobals.instance.somevalue + "!"

根据需要调整/扩展/获取广告素材。如果您想避免输入这么多内容,请随意使用较短的类名(如G表示全局)。您也可以改为使用访问者类方法,甚至跳过它们之间的instance。这一切都只是Ruby(不是Cucumber),因此不再涉及Cucumber魔法了。

提示:您希望很早就加载此模块。我确信有一个很好的方法可以做到这一点"干净利落地#34;但我选择以Cucumber(000_...)首先找到的方式命名它。 / p>