使用 rspec 测试 ruby 程序

Testing ruby program with rspec

目前我正在学习 ruby ,我想学习如何使用 rspec 和 BDD 开发应用程序,但我之前从未做过任何类型的测试。我很难思考写作行为-> 制定方向。我已经为 rspec 找到了一些简单的初学者教程,但对于我在没有 类 的情况下构建小程序的情况并没有多大帮助。

这是我的代码。简单的 Cesar 密码轮换程序。快速简短...当用户输入 ROT 后跟 0-26 和文本例如 "ROT24 some text" 它检查输入的格式是否正确并在范围内,然后根据 ROT 字后的数字旋转文本中的字符。示例 ROT5 按字母顺序将字符旋转 5 个位置。

i=0
#check input

while true

puts
    if i>0
        puts "Wrong Entry Please Try Again!"

        puts "Input Decipher key in ROT0-ROT26 format and text to decipher using white space between. Example (ROT2 SomeText)"
        input=gets.chop

    else
        puts "Input Decipher key in ROT0-ROT26 format and text to decipher using white space between. Example (ROT2 SomeText)"
        input=gets.chop
        i+=1
    end

 break if input.match(/\AROT([0-9]|1[0-9]|2[0-6]) /) 

end



#splitting input
inputArray=input.split(" ",2)

inputFirstPart= inputArray[0]

inputKey=inputFirstPart[3..4].to_i

inputText= inputArray[1]

#cipher method
def rotate (str,num)

    alphabetLow = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
    alphabetUp = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
    second_step=str.tr(alphabetLow.join,alphabetLow.rotate(num).join)
    second_step.tr(alphabetUp.join,alphabetUp.rotate(num).join)

end
#output result 
print "Your result is: "
print rotate(inputText,inputKey)
puts

任何人(如果有空闲时间给这个可怜的人)都可以为这段代码编写 rspec 测试以便我可以对其进行逆向工程吗?我尝试了一些东西,但最重要的是我对用户输入感到困惑,因为在测试期间它要求我实际进行对我来说毫无意义的输入。

提前致谢。

首先,您需要将实际要测试的代码部分拆分到一个单独的文件中,该文件将代码放入 class。然后,您可以 require 您正在 运行ning 的文件中的代码,接受来自输入的数据,并将该数据传递给它。同时,spec 文件也会 require 文件,并且 运行 specs 会针对 class 中的方法。可能看起来像:

rotator.rb:

class Rotator
    def rotate(str, num)
        #do stuff
    end
end

rotator_spec.rb

require_relative 'rotator'
describe Rotator do
    it 'rotates' do
        expect(described_class.new.rotate('a', 'b')).to eq 'result'
    end
end

run.rb

require_relative 'rotator'
rotator = Rotator.new
#do input stuff
puts rotator.rotate(inputText, inputKey)

首先,让我们将您的代码重构为自己的代码 class:

caesar.rb

class Caesar
  def self.rotate (str, num)
    alphabet_low = ('a'..'z').to_a # Shorthand for alphabet creation, thanks Ruby!
    alphabet_high = ('A'..'Z').to_a

    second_step = str.tr(alphabet_low.join, alphabet_low.rotate(num).join)
    second_step.tr(alphabet_high.join, alphabet_high.rotate(num).join)
  end
end

接下来我们需要安装rspec gem:

$ gem install rspec

让我们添加一个 spec 目录并在其中创建一个 rspec 文件:

spec/caesar_spec.rb

require_relative '../caesar'

describe Caesar do
  describe '.rotate' do
    context 'when number 0 is provided' do
      let(:number) { 0 }

      it 'returns the same text that is provided' do
        string = 'Hello World'
        expect(Caesar.rotate(string, number)).to eq('Hello World')
      end
    end

    context 'when number 1 is provided' do
      let(:number) { 1 }

      it 'encrypts the given string by rotating it a single character' do
        string = 'Hello World'
        expect(Caesar.rotate(string, number)).to eq('Ifmmp Xpsme')
      end
    end
  end
end

现在从项目文件夹中的命令行,只需 运行 rspec:

$ rspec

结果应该是:

..

Finished in 0.00222 seconds (files took 0.09387 seconds to load)
2 examples, 0 failures