4

我正在使用 rspec 对设备进行系统测试。该设备是模块化的,因此可以将任意数量的子设备连接到测试台。有很多地方我想编写测试,这些测试将遍历连接的子设备并在每个设备上运行相同的测试。

基本上,这就是我想要做的:

before(:all)   
  @tool = discover_sub_devices()
  @tool.sub_devices.should == exp_sub_device_list
end

describe "some sub device tests" do
  @tool.sub_devices.each do |dev|   
    it "should succeed at doing things" do
      dev.do_thing.should == success   
    end 
  end
end

不幸的是,这不起作用。sub_devices我收到错误说 @tool 是 nill 并且在测试运行之前不包含一个类。before(:all)所以测试在块运行之前被解析。

我可以使它工作的一种方法是将循环放在it块内。像这样:

it "should succeed at doing things" do
  @tool.sub_devices.each do |dev| 
    dev.do_thing.should == success   
  end
end

这样做的问题是,即使第一个失败,我也真的想测试所有子设备。我想查看究竟有多少子设备发生故障的报告。此代码将在一个失败时立即中断,而不是测试其余部分。

我意识到这可能不是 rspec 的正常用例,但如果我能完成这项工作,它将非常方便我们的测试情况。

有什么建议么?

4

2 回答 2

1

这里有一些写作技巧。

最好避免使用before :all. 最好避免在示例之外创建对象。

describe "some sub device tests" do

  let(:tool) { discover_sub_devices }

  it "matches the sub device list" do
    tool.sub_devices.should be == expected_sub_devices_list
  end

  it "succeeds with all sub-devices" do
    failures = tool.sub_devices.reject{|d| d.do_thing == success}

    # option 1
    failures.should be_empty # will show just a yes/no result

    # option 2
    failures.size.should be == 0 # will show the number of failures

    # option 3
    failures.should be == [] # will display all sub-devices which fail
  end

end
于 2013-09-16T14:44:03.570 回答
0

您面临的问题是describe块的主体会立即执行,而let,beforeit块的主体会在以后执行。

假设您不需要每次都重新发现设备,您可以按如下方式重构代码,从而消除before调用:

describe "some sub device tests" do
  tool = discover_sub_devices()
  it "should discover sub devices correctly" do
     tool.sub_devices.should == exp_sub_device_list
  end
  tool.sub_devices.each do |dev|   
    it "should succeed at doing things" do
      dev.do_thing.should == success   
    end 
  end
end
于 2013-09-16T14:02:19.557 回答