0

最後の 2 つのテストはどちらも個別に機能しますが、両方を実行するように設定すると (非保留)、問題が発生します。

質問: 2 つを 1 つにマージするテストを作成できますか? これはどのように見えますか? (はい、rspec は初めてです)

require_relative '../spec_helper'

# the universe is vast and infinite....and...it is empty
describe "tic tac toe game" do
  context "the game class" do

    before (:each) do
      player_h = Player.new("X")
      player_c = Player.new("O")
      @game = Game.new(player_h, player_c)
    end

   it "method drawgrid must return a 3x3 game grid" do
      @game.drawgrid.should eq("\na #{$thegrid[:a1]}|#{$thegrid[:a2]}|#{$thegrid[:a3]} \n----------\nb #{$thegrid[:b1]}|#{$thegrid[:b2]}|#{$thegrid[:b3]} \n----------\nc #{$thegrid[:c1]}|#{$thegrid[:c2]}|#{$thegrid[:c3]} \n----------\n  1 2 3 \n")
      @game.drawgrid
   end
   #FIXME - last two test here - how to merge into one?
   it "play method must display 3x3 game grid" do
      STDOUT.should_receive(:puts).and_return("\na #{$thegrid[:a1]}|#{$thegrid[:a2]}|#{$thegrid[:a3]} \n----------\nb #{$thegrid[:b1]}|#{$thegrid[:b2]}|#{$thegrid[:b3]} \n----------\nc #{$thegrid[:c1]}|#{$thegrid[:c2]}|#{$thegrid[:c3]} \n----------\n  1 2 3 \n").with("computer move")
      @game.play
    end
    it "play method must display 3x3 game grid" do
      STDOUT.should_receive(:puts).with("computer move")
      @game.play
    end
  end
end

参考までに、ここに play メソッドを含むコードを示します

require_relative "player"
#
#Just a Tic Tac Toe game class
class Game
  #create players
  def initialize(player_h, player_c)
    #bring into existence the board and the players
    @player_h = player_h
    @player_c = player_c
    #value hash for the grid lives here
    $thegrid = {
        :a1=>" ", :a2=>" ", :a3=>" ",
        :b1=>" ", :b2=>" ", :b3=>" ",
        :c1=>" ", :c2=>" ", :c3=>" "
    }
    #make a global var for drawgrid which is used by external player class
    $gamegrid = drawgrid

  end
  #display grid on console
  def drawgrid

    board = "\n"
    board << "a #{$thegrid[:a1]}|#{$thegrid[:a2]}|#{$thegrid[:a3]} \n"
    board << "----------\n"
    board << "b #{$thegrid[:b1]}|#{$thegrid[:b2]}|#{$thegrid[:b3]} \n"
    board << "----------\n"
    board << "c #{$thegrid[:c1]}|#{$thegrid[:c2]}|#{$thegrid[:c3]} \n"
    board << "----------\n"
    board << "  1 2 3 \n"
    return board

  end
  #start the game
  def play
    #draw the board
    puts drawgrid
    #external call to player class
    @player = @player_c.move_computer("O")
  end
end

player_h = Player.new("X")
player_c = Player.new("O")


game = Game.new(player_h, player_c)
game.play

更新 - エラー出力のテスト完全を期すために.... rspec spec の実行からの完全な出力を次に示します...

    gideon@thefonso ~/Documents/ca_ruby/rubytactoe (now-with-rspec)$ rspec spec

    a  | |  
    ----------
    b  | |  
    ----------
    c  | |  
    ----------
      1 2 3 
    computer move

    tic tac toe game
      the game class
        method drawgrid must return a 3x3 game grid

    An error occurred in an after(:each) hook
      RSpec::Mocks::MockExpectationError: (#<IO:0x007f948406fcf0>).puts(any args)
        expected: 1 time
        received: 0 times
      occurred at /Users/gideon/Documents/ca_ruby/rubytactoe/spec/game_spec.rb:18:in `block (3 levels) in <top (required)>'

        play method must display 3x3 game grid (FAILED - 1)

    An error occurred in an after(:each) hook
      RSpec::Mocks::MockExpectationError: (#<IO:0x007f948406fcf0>).puts("computer move")
        expected: 1 time
        received: 0 times
      occurred at /Users/gideon/Documents/ca_ruby/rubytactoe/spec/game_spec.rb:22:in `block (3 levels) in <top (required)>'

        play method must display 3x3 game grid (FAILED - 2)

    tic tac toe game
      the player class
        must have a human player X
        must have a computer player O

    Failures:

      1) tic tac toe game the game class play method must display 3x3 game grid
         Failure/Error: STDOUT.should_receive(:puts).and_return("\na #{$thegrid[:a1]}|#{$thegrid[:a2]}|#{$thegrid[:a3]} \n----------\nb #{$thegrid[:b1]}|#{$thegrid[:b2]}|#{$thegrid[:b3]} \n----------\nc #{$thegrid[:c1]}|#{$thegrid[:c2]}|#{$thegrid[:c3]} \n----------\n  1 2 3 \n").with("computer move")
         NoMethodError:
           undefined method `with' for #<Proc:0x007f9484341168>
         # ./spec/game_spec.rb:18:in `block (3 levels) in <top (required)>'

      2) tic tac toe game the game class play method must display 3x3 game grid
         Failure/Error: @game.play
           #<IO:0x007f948406fcf0> received :puts with unexpected arguments
             expected: ("computer move")
                  got: ("\na  | |  \n----------\nb  | |  \n----------\nc  | |  \n----------\n  1 2 3 \n")
         # ./lib/game.rb:37:in `puts'
         # ./lib/game.rb:37:in `play'
         # ./spec/game_spec.rb:23:in `block (3 levels) in <top (required)>'

    Finished in 0.00457 seconds
    5 examples, 2 failures

    Failed examples:

    rspec ./spec/game_spec.rb:17 # tic tac toe game the game class play method must display 3x3 game grid
    rspec ./spec/game_spec.rb:21 # tic tac toe game the game class play method must display 3x3 game grid
    gideon@thefonso ~/Documents/ca_ruby/rubytactoe (now-with-rspec)$ 
4

1 に答える 1

1

質問には、どのような「問題」が発生するかを含める必要があります。何がうまくいかなかったかを診断するのに役立ちます。

これが答えですが、後で注意が必要です。他の方法があります。

it "play method must display 3x3 game grid" do
  STDOUT.should_receive(:puts).with("\na #{$thegrid[:a1]}|#{$thegrid[:a2]}|#{$thegrid[:a3]} \n----------\nb #{$thegrid[:b1]}|#{$thegrid[:b2]}|#{$thegrid[:b3]} \n----------\nc #{$thegrid[:c1]}|#{$thegrid[:c2]}|#{$thegrid[:c3]} \n----------\n  1 2 3 \n").twice.ordered
  STDOUT.should_receive(:puts).with("computer move").once.ordered

  @game.play
  @game.play
end

警告:現在テストしている方法を維持することは不可能です。移動テスト中に出力をチェックするパスを続行しない可能性があります。出力を個別にテストしますが、移動メカニズムを分離して、たとえば、配列値、または移動が誰であるかを示すフラグなどをチェックできるようにします。 。

また、移動計算ロジックではなく、実際に順次移動をテストするかどうかを決定する必要があります。連続移動には、上記のような刺激的なテスト構造、テスト順序の強制、または移動の順序が正しいことを確認する必要があります。

具体的には、何をいつテストしているのかを再考する方が理にかなっているかもしれません。

于 2012-09-04T04:16:44.067 に答える