【发布时间】:2013-12-02 13:21:52
【问题描述】:
我正在编写一个简单的程序,用于将汇编语言指令转换为我们正在构建的处理器各自的 24 位二进制指令。我正在用 Ruby (2.0.0) 编写程序并使用 Rspec (2.14.6) 对其进行测试。奇怪的是我可以运行两个相同的测试——一个失败,另一个成功。这是一个例子:
测试失败:
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 "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 两次,但它对以下两个测试做了奇怪的事情,所以我将第二个测试更改为与第一个匹配,但它仍然失败。另外,如果我注释掉第一个测试(这两个),第二个通过。换句话说,只有当我同时运行两个测试时它才会失败——而不是另一个。
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
输出:
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 附加到末尾,如...
001000001110010100010010
0010000011100101000100001110010100010010
00100000111001010001000011100101000100001110010100010010
etc..
所以...这不是 rspec ;) 我将不得不进一步深入研究我的代码以找出问题所在。
编辑 2
对于那些想知道(我想知道)的人,在我的代码中,我发现了一个地方,我必须返回对对象的引用而不是值。这导致原始对象被修改(我的头受伤并且测试失败!):
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
我改成这样了:
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
【问题讨论】:
-
能否提供
::build_instruction的出处?似乎Parser代码中的某些内容导致了这种情况发生。您是否测试过在 RSpec 之外运行这些方法(包括两次相同的方法)? -
@micahbf:“您是否测试过在 RSpec 之外运行这些方法(包括两次相同的方法)”- 好建议。我在 rspec 之外运行过它——但不是多次。我更新了我的问题:)