测试复杂的方法

时间:2011-11-30 17:09:10

标签: ruby testing rspec

我正在开发一个checkers实现,我有几十个容易测试的方法,但我不知道如何测试我的主#play_game方法。我的大多数方法都很容易确定输入和输出,因此很容易测试,这种方法是多方面的,并且实际上没有容易辨别的输出。这是代码:

def play_game
    puts @gui.intro

    while(game_over? == false)
      message = nil
      @gui.render_board(@board)
      @gui.move_request
      player_input = gets 
      coordinates = UserInput.translate_move_request_to_coordinates(player_input) 

      message = MoveCheck.move_validator(coordinates[0], coordinates[1], coordinates[2], coordinates[3])
      puts message unless (message.nil? or message == "jumping move")
      if(message == nil or message == "jumping move")
        @current_player = switch_player unless (message == "jumping move" and jump_available? == true)
      end
    end
    puts @gui.display_game_ending_message  
  end

那么我该如何测试(使用RSpec)或者我不应该担心它并且真的在我的全面测试中呢?

2 个答案:

答案 0 :(得分:6)

所有play_game真正在做的是运行游戏循环。你真正想要测试的是游戏循环中内部发生的事情。最简单的方法是将游戏循环的内容分解为更容易测试的方法。

一旦你将游戏循环作为一系列方法,你就可以更容易地单独测试它们。

答案 1 :(得分:4)

我将中的所有代码移动到 -loop中的单独方法。通过这种方式,您可以通过将不同的游戏状态作为输入并检查它们是否已成功处理(以获得游戏状态)来轻松测试它。请注意,遵循功能编程原则的代码更容易测试(new_state = process(old_state)),但无论如何,您仍然可以按原样进行测试,检查@gui是否按照您之前的状态更新

您的主play_game方法现在就像以下一样简单:

def play_game
  process(@gui) until game_over?
end

[edit]让我展示一个真实的例子。为了玩Raphael.js和CoffeeScript,我写了一个Reversi引擎(reversi.coffeespec)。您的问题中的主循环代码在无状态函数中被隔离:move。所以我可以做new_state = move(old_state)并用所有对测试它* old_state * / * expected_new_states *我觉得合适。