使用来自控制台的用户输入运行的测试程序

时间:2015-11-22 12:22:10

标签: ruby minitest

我正在为电梯建模系统编写测试。例如,我想测试电梯是否可以改变方向,并且可以移动到指定的楼层。

我有以下方法:

def initialize
  @current_floor = 0
  @requested_floor = 0
end
def get_value
  gets.chomp
end
def arrival
  print "Enter floor number: "
  @requested_floor = get_value
  # only proceed if user entered an integer
  if validate_floor_number(@requested_floor)
    @requested_floor = @requested_floor.to_i
    move
  else
    arrival
  end
end
def move
  msg = ""
  @current_floor < @requested_floor ? msg = "Going Up!" : msg = "Going Down"
  puts msg
  @current_floor = @requested_floor
  next_move
end
def next_move
  puts "Do you want to go to another floor? Y/N"
  another_floor = (get_value).upcase
  another_floor == 'N' ? final_destination : arrival
end

我通过致电Elevator.new.arrival来启动该计划。要检查电梯是否已更改方向,我需要将@current_floor的值存储在临时变量中,然后在调用move后检查其值是否已更改。

由于this question中的答案,我正在使用IO管道从控制台测试输入,但我不确定如何将这些知识应用于方法的一部分的用户交互。

如何模拟从一开始(Elevator.new.arrival)到move方法运行的程序,在那里停止,这样我就可以检查{{1}的值 - 所有这些都没有运行程序本身并使用IO管道来模拟用户交互?

我感觉我可能以错误的方式进行了程序的设计。如果有人能指出我正确的方向来解决这个问题我会很感激。

修改

根据Wand Maker的建议,我写了一个测试如下:

@current_floor

不幸的是,当我运行我的测试文件时,程序仍然运行并提示用户输入。也许我正在调用 describe "checks that the elevator can change directions" do before do moves = [3, 'Y', 5, 'Y', 2, 'Y', 7, 'N'] def get_value; moves.next end end it "should stop on floor 7" do Elevator.new.arrival assert_equal(@current_floor, 7) end end ,但我想不出另一种方法。

2 个答案:

答案 0 :(得分:0)

this answer所示,您可以覆盖getvalue以提供用户输入。

以下是完整的代码,无需实际使用gets即可运行。我不得不添加几个缺失的方法 - validate_floor_numberfinal_destination

require 'minitest/autorun'

class Elevator
  attr_accessor :current_floor

  def initialize
    @current_floor = 0
    @requested_floor = 0
    #@last_floor = false
  end

  def get_value
    gets.chomp
  end

  def validate_floor_number(v)
    v.to_i rescue false
  end

  def arrival
    print "Enter floor number: "
    @requested_floor = get_value

    # only proceed if user entered an integer
    if validate_floor_number(@requested_floor)
      @requested_floor = @requested_floor.to_i
      move
    else
      arrival
    end
  end

  def move
    msg = ""
    @current_floor < @requested_floor ? msg = "Going Up!" : msg = "Going Down"
    puts msg
    @current_floor = @requested_floor
    next_move
  end

  def final_destination 
    puts "Reached your floor"
  end

  def next_move
    puts "Do you want to go to another floor? Y/N"
    another_floor = (get_value).upcase
    another_floor == 'N' ? final_destination : arrival
  end

 end 

 describe "checks that the elevator can change directions" do
    before do
      class Elevator
          @@moves = [3, 'Y', 5, 'Y', 2, 'Y', 7, 'N'].each
          def get_value; @@moves.next end
      end
    end

    it "should stop on floor 7" do
      e = Elevator.new
      e.arrival
      assert_equal(e.current_floor, 7)
    end
 end

以上程序的输出:

Run options: --seed 2561

# Running:

Enter floor number: Going Up!
Do you want to go to another floor? Y/N
Enter floor number: Going Up!
Do you want to go to another floor? Y/N
Enter floor number: Going Down
Do you want to go to another floor? Y/N
Enter floor number: Going Up!
Do you want to go to another floor? Y/N
Reached your floor
.

Finished in 0.001334s, 749.4982 runs/s, 749.4982 assertions/s.

1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
[Finished in 0.3s]

答案 1 :(得分:0)

这回答了你的问题的这一部分:如何通过移动方法模拟从一开始运行的程序(Elevator.new.arrival)并将其停在那里以便我可以检查@current_floor的价值?

  1. 安装byebug:if (b == 0) textBox3.Text = "Error, cannot divide by zero"; else { result = a / b; textBox3.Text = result.ToString(); }
  2. 在您的文件中要求:gem install byebug
  3. 在您要停止程序的位置添加require 'byebug'命令,例如在byebug开始时(请参阅帖子末尾的代码)
  4. 您被放入shell并可以检查所有内容,例如move通过输入或使用@current_floor
  5. 来检查实例
  6. 如果您想继续,请点击self,程序将继续(您可能已做过任何修改)
  7. 这应该可以帮助你调试它。

    CTRL+D