首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >相同的rspec测试分别成功和失败

相同的rspec测试分别成功和失败
EN

Stack Overflow用户
提问于 2013-11-19 05:33:00
回答 2查看 409关注 0票数 0

我正在编写一个简单的程序,将汇编语言指令转换为它们各自的24位二进制指令,用于我们正在构建的处理器。我正在用Ruby (2.0.0)编写程序,并使用Rspec (2.14.6)进行测试。奇怪的是,我可以运行两个相同的测试,一个失败,另一个成功。下面是一个示例:

考试不及格:

代码语言:javascript
复制
it "Returns 24-bit binary instruction for valid line of assembly code" do

  #...25 other instructions are tested before these...
  expect(Parser.build_instruction("Li r2, 0000111001010001")).to eq("001000001110010100010010")
  expect(Parser.build_instruction("Li r2, 0000111001010001")).to eq("001000001110010100010010")

end

通过考试:

代码语言:javascript
复制
it "Returns 24-bit binary instruction for valid line of assembly code" do

  #...25 other instructions are tested before these...
  expect(Parser.build_instruction("Li r2, 0000111001010001")).to eq("001000001110010100010010")
  #expect(Parser.build_instruction("Li r2, 0000111001010001")).to eq("001000001110010100010010")

end

我开始怀疑,在一个it...do...end块中是否可能有太多的测试(或者两次运行同一个expect是否有问题),但我尝试复制前两次以上的一些测试,测试继续通过。我还尝试将一些测试拉到他们自己的it...do...end块中,然后导致不同的期望(之前通过的)失败。我有点困惑。想法?

实际上我不想运行同一个expect两次,但是它对下面两个测试做了一些奇怪的事情,所以我更改了第二个测试以匹配第一个测试,但是它仍然失败了。另外,如果我注释掉第一个测试(这两个测试中的一个),第二个测试就通过了。换句话说,只有当我同时运行两种测试时,它才会失败--而不是另一种。

代码语言:javascript
复制
it "Returns 24-bit binary instruction for valid line of assembly code" do

  #...25 other instructions are tested before these...
  expect(Parser.build_instruction("Li r2, 0000111001010001")).to eq("001000001110010100010010")
  expect(Parser.build_instruction("Li r2, 111001010001")).to eq("001000001110010100010010")

end

输出:

代码语言:javascript
复制
1) Parser Returns 24-bit binary instruction for valid line of assembly code
 Failure/Error: expect(Parser.build_instruction("Li r2, 111001010001")).to eq("001000001110010100010010")

   expected: "001000001110010100010010"
        got: "0010000011100101000100001110010100010010"

   (compared using ==)
 # ./spec/parser_spec.rb:65:in `block (2 levels) in <top (required)>'

编辑1

@micahbf和@felix,我有一个方法,它接受一个输入文件,在每一行上都有一个指令,以便将其转换为二进制代码。我只是在一个输入文件上运行它,Li r2, 111001010001重复了50次(我应该在:/之前这样做),而且只有第一个输出是正确的--后面的行将1110010100010010追加到末尾,如.

代码语言:javascript
复制
001000001110010100010010
0010000011100101000100001110010100010010
00100000111001010001000011100101000100001110010100010010
etc..

所以.这不是rspec ;)我必须进一步研究我的代码,才能找出症结所在。

编辑2

对于那些希望知道(我想知道)的人,在我的代码中,我找到了一个地方,在那里我必须返回对对象的引用,而不是返回值。这导致原始对象被修改(我的头受伤了,测试失败了):

代码语言:javascript
复制
def self.get_reg_code reg
    @logger.debug { "Getting register code for [ #{reg.inspect} ]" }
    reg.upcase!
    if register? reg
      return CODES["#{reg}".to_sym] # <-- Returning object reference!
    else
      return reg
    end
end

我把它改成了这个

代码语言:javascript
复制
def self.get_reg_code reg
    @logger.debug { "Getting register code for [ #{reg.inspect} ]" }
    reg.upcase!
    if register? reg
      reg_code = CODES["#{reg}".to_sym].clone # <-- Return a copy--not the referenced object!
      return reg_code
    else
      return reg
    end
end
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-19 06:26:26

对不起,看起来rspec是对的,Parser是错的,。:)

特别是考虑到它的失败(“001000001110010100010000111001010010”),它看起来就像是Parser有某种状态来存储指令。

要验证这一假设,请第三次运行代码(但第二次没有预期)。你收集了一个关于我的状态假设的论点,如果失败了,你会读到"001000001110010100010000111001010001001000100001110010100010010".。

“测试”的另一种方法是为build_instructions的每个调用创建一个新的解析器实例。实际上不是为了回避这个问题,而是为了调查它。

你可能还需要这样的东西

代码语言:javascript
复制
describe "#build_instruction"
  it "resets state" do
    expect(Parser.build_instruction("Li r2, 0000111001010001")).to eq("001000001110010100010010")
    expect(Parser.build_instruction("Li r2, 111001010001")).to     eq("001000001110010100010010")
  end
end

在那里显式地测试行为。

票数 1
EN

Stack Overflow用户

发布于 2013-11-19 14:16:51

在测试前有一个已知的状态是很重要的。因此,应该对每个测试进行设置和删除。还有一项一般性建议,即“每次测试只有一个断言”。

基于此,我将继续将测试移到它自己的it...end块中。你提到尝试,但有一个问题,但没有显示问题。我会走这条路。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20063942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档