用RSpec构建CSV数据驱动的测试是最简单的方法吗?

用RSpec构建CSV数据驱动的测试是最简单的方法吗?,rspec,rspec2,rspec3,Rspec,Rspec2,Rspec3,我是Ruby和RSpec的新手,做了一些研究,发现有几种方法可以从在线帖子中进行数据驱动的枚举测试,但它们不像完整的教程那样涉及到很多细节。所以在我再次详细阅读这些在线文章之前,我想我应该先问一下这里 这里的设置是基于使用RSpec的标准简单方法(定义了descripe&it块,而不是仅导入RSpec的部分来实现期望)。然后,我尝试将数据驱动能力添加到it中: require 'rspec' require 'csv' describe "test suite name" do befor

我是Ruby和RSpec的新手,做了一些研究,发现有几种方法可以从在线帖子中进行数据驱动的枚举测试,但它们不像完整的教程那样涉及到很多细节。所以在我再次详细阅读这些在线文章之前,我想我应该先问一下这里

这里的设置是基于使用RSpec的标准简单方法(定义了descripe&it块,而不是仅导入RSpec的部分来实现期望)。然后,我尝试将数据驱动能力添加到it中:

require 'rspec'
require 'csv'

describe "test suite name" do
  before :all do
    #this CSV mapping method found online...
    @device_client = CSV.read path
    @descriptor = @device_client.shift
    @descriptor = @descriptor.map { |key| key.to_sym }
    @device_client.map { |client| Hash[ @descriptor.zip(client) ] }
  end

  @device_client.each do |client|
    describe "#{client[:test_scenario]}" do
      if "match some CSV field value"
        it "should run this kind of test" do
          #additional code as needed
          expect(some_actual).to eql(some_expected)
        end
      end

      if "match some other CSV field value"
        it "should run that kind of test" do
          #additional code as needed
          expect(some_actual).to eql(some_expected)
        end
      end

      it "some other test common to all CSV rows" do
        #stuff
      end
    end
  end

end
这里我注意到@device\u client是nil,因为它现在是结构化的(使用“p@device\u client”语句进行调试以转储内容)。为了让它有值,我必须将散列包含在它所在的it块中(我通常在另一个descripe块中包含散列,不过假设我可以跳过额外的descripe)

我如何重新构造测试,以“读取”相同的内容(对测试的读者)并按照我所希望的方式运行?如果重组意味着我不能使用标准的RSpec格式,必须以不同的方式要求RSpec组件,那也没关系(网上的帖子似乎没有遵循简单/基本的RSpec格式)

我认为我的代码很难解释。如果不是,目的是使用CSV输入动态构建测试。每个CSV行都是一个具有多个测试的场景-1个测试根据CSV字段值而不同,因此ifs、其余测试对所有场景都是通用的。我们对文件中的所有CSV场景行重复此设置。在我们处理CSV数据之前,所有前块是全局设置


在重构过程中,理想情况下,我希望保留descripe&it文本描述块(或与之相当的部分),以便在测试结果中显示它们对测试的描述,而不仅仅是一堆期望值。

类似的功能应该可以工作:

require 'csv'

describe "test suite name" do
  device_client = CSV.read path
  descriptor = device_client.shift
  descriptor = descriptor.map { |key| key.to_sym }
  clients = device_client.map { |client| Hash[ descriptor.zip(client) ] }

  clients.each do |client|
    describe "#{client[:test_scenario]}" do
      if "match some CSV field value"
        it "should run this kind of test" do
          #additional code as needed
          expect(some_actual).to eql(some_expected)
        end
      end

      if "match some other CSV field value"
        it "should run that kind of test" do
          #additional code as needed
          expect(some_actual).to eql(some_expected)
        end
      end

      it "some other test common to all CSV rows" do
        #stuff
      end
    end
  end
end
您的版本的显著变化:

  • 无需要求
    rspec
    (运行
    rspec
    命令时,rspec将自行加载)
  • 我将CSV逻辑从(:all)之前的
    中移到
    descripe
    正文中。以前的问题是,在定义了所有示例和组之后,在执行特定组之前,会运行
    before
    hook。您需要在规范定义期间(执行
    descripe
    块期间)利用CSV文件内容
  • 我从实例变量切换到局部变量。您之前所做的一切都不起作用,因为(:all)钩子在示例组类的实例上下文中运行,正如描述块在类本身的上下文中运行一样,因此它们在不同的上下文中运行,并且不能访问相同的实例变量。一旦我们将逻辑移到
    descripe
    块中,您就可以使用简单的局部变量
  • 我在(:all)逻辑之前的
    最后一行添加了
    clients=
    。您之前所拥有的是丢弃
    device\u client.map{…}
    的结果,但我假设这就是您想要使用的

有关
description
before
块之间范围差异的更多信息,请参阅。

感谢,以获得解决方案和深入的信息。