我正在开发一个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)或者我不应该担心它并且真的在我的全面测试中呢?
答案 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.coffee和spec)。您的问题中的主循环代码在无状态函数中被隔离:move
。所以我可以做new_state = move(old_state)
并用所有对测试它* old_state * / * expected_new_states *我觉得合适。