【问题标题】:Rspec: testing looping arrays , input = [] , output =[] for custom classes. rubyRspec:测试自定义类的循环数组,输入 = [],输出 =[]。红宝石
【发布时间】:2013-07-17 23:12:43
【问题描述】:

我正在尝试使用我用来开发输出中的函数的示例来加快我的测试开发。

我有两个数组:输入和输出。

function(input[0]) == output[0].

循环正在工作,但它卡在最后一个索引中。例如:如果 input.length = 10 它总是做 function(input[10]) == output[10].

describe "multiple_chords" do
  input = ["A7 DMaj79", "E-7 A7", "D-7 G7", "Bb-7b5 Eb7b9" , "Bb-7b5 Eb7", "G7 A7", "D-7b5 G7b9", "D-79 G#7913"]
  output = [[{"root"=>"A", "def"=>"7"}, {"root"=>"D", "def"=>"Maj7"}], [{"root"=>"E", "def"=>"-7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7"}, {"root"=>"G", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "def"=>"7"}], [{"root"=>"G", "def"=>"7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7b5"}, {"root"=>"G", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]]

  for i in 0..input.length-1
    it "analyzes correctly #{input[i]}" do
      expect(IpmChords::multiple_chords(input[i])).to eq(output[i])
    end
  end
end

控制台的输出是:

 6) IpmChords multiple_chords analyzes correctly Bb-7b5 Eb7
 Failure/Error: expect(IpmChords::multiple_chords(input[i])).to eq(output[i])

   expected: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
        got: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>"13", "def"=>""}]

   (compared using ==)

   Diff:
   @@ -1,3 +1,3 @@
    [{"root"=>"D", "tensions"=>"9", "def"=>"-7"},
   - {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
   + {"root"=>"G#", "tensions"=>"13", "def"=>""}]

 # ./spec/ipm_classes/ipm_chords_ipm_class_spec.rb:28:in `block (4 levels) in <top (required)>'

7) IpmChords multiple_chords analyzes correctly E-7 A7
 Failure/Error: expect(IpmChords::multiple_chords(input[i])).to eq(output[i])

   expected: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
        got: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>"13", "def"=>""}]

   (compared using ==)

   Diff:
   @@ -1,3 +1,3 @@
    [{"root"=>"D", "tensions"=>"9", "def"=>"-7"},
   - {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
   + {"root"=>"G#", "tensions"=>"13", "def"=>""}]

你可以看到它总是在计算相同的数组索引,但是每次循环迭代的测试名称都会改变:

6) IpmChords multiple_chords analyzes correctly Bb-7b5 Eb7
7) IpmChords multiple_chords analyzes correctly E-7 A7

我认为这将节省大量时间,而且它应该可以工作,不是吗? 希望您能够帮助我。 谢谢

【问题讨论】:

    标签: ruby-on-rails ruby arrays loops rspec


    【解决方案1】:

    您在这里遇到了 Ruby 的块绑定的一些问题。发生的事情是每个块都将绑定到i,它仍然在范围内,这意味着它们被调用,它们都将使用i最终成为的任何东西(这将是最后一个数组索引)。

    如果您改用 Ruby 的块迭代器,它会起作用:

    describe "multiple_chords" do
      input = ["A7 DMaj79", "E-7 A7", "D-7 G7", "Bb-7b5 Eb7b9" , "Bb-7b5 Eb7", "G7 A7", "D-7b5 G7b9", "D-79 G#7913"]
      output = [[{"root"=>"A", "def"=>"7"}, {"root"=>"D", "def"=>"Maj7"}], [{"root"=>"E", "def"=>"-7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7"}, {"root"=>"G", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "def"=>"7"}], [{"root"=>"G", "def"=>"7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7b5"}, {"root"=>"G", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]]
    
      input.each_with_index do |chord, index|
        it "analyzes correctly #{chord}" do
          expect(IpmChords::multiple_chords(chord)).to eq(output[index])
        end
      end
    end
    

    这样做的原因是您最终不会在保留在范围内的每个块之外创建一个变量,因此每个块最终都会以正确的值被调用。每个循环产生的值是该循环的本地值,因此您不会“溢出”。

    顺便说一句,惯用的 Ruby 通常期望使用枚举器而不是 for 循环。

    关于风格的说明;您可以通过定义然后迭代预期输入和输出的哈希来稍微清理一下:

    describe "multiple_chords" do
      CHORD_MAP = {
        "A7 DMaj79" => [{"root"=>"A", "def"=>"7"}, {"root"=>"D", "def"=>"Maj7"}],
        "E-7 A7"    => [{"root"=>"E", "def"=>"-7"}, {"root"=>"A", "def"=>"7"}],
        # ...
      }
    
      CHORD_MAP.each do |chord, result|
        it "analyzes correctly #{chord}" do
          expect(IpmChords::multiple_chords(chord)).to eq(result)
        end
      end
    end
    

    【讨论】:

    • Chris 的回答很好,值得肯定。我已经针对使我的 rspec 测试数据驱动的一般情况调整了这种方法。
    猜你喜欢
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 2010-10-22
    相关资源
    最近更新 更多