【问题标题】:Testing ruby program with rspec使用 rspec 测试 ruby​​ 程序
【发布时间】:2018-02-21 10:06:37
【问题描述】:

此时我正在学习 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 测试,以便我可以对其进行逆向工程吗?我尝试了几件事,但最重要的是我对用户输入感到困惑,因为在测试期间它要求我实际进行输入,这对我来说毫无意义。

提前谢谢你。

【问题讨论】:

    标签: ruby testing rspec bdd


    【解决方案1】:

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

    凯撒.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
    

    让我们添加一个规范目录并在其中创建一个 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
    

    【讨论】:

      【解决方案2】:

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

      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
      

      运行.rb

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多