Rubyのテストコード(test-unit)

Rubyでジャンケンプログラムを製作し、勝ち負けの判定が正しいか、test-unitを使用して確認しました。

まずジャンケンのコードです。

hands = ["g", "c", "p"]
hands_name = {"g" => "グー","c" => "チョキ","p" => "パー"}


puts "じゃんけん…"
your_hand = gets.chomp
puts "ポン!"

com_hand = hands.sample
num = hands.index(your_hand)

print "あなたは#{hands_name[your_hand]}、わたしは#{hands_name[com_hand]}"

if hands[num - 2] == com_hand
  puts "あなたの勝ちです"
elsif hands[num - 1] == com_hand
  puts "あなたの負けです"
else
  puts "引き分けです"
end

このコードではジャンケンの手の配列をhands = ["g", "c", "p"]としていますが、この配列では
indexが1小さい要素には負け、indexが2小さい要素に勝つ
という性質がありそうなので、これを利用して場合分けを減らせそうです。

f:id:fumiyaokabe:20180612102107p:plain
テストプレイです。一見正しそうですね。

ではtest-unitを用いて全てのパターンで判定が正しいか確認してみます。


まずは'test/unit'をrequireし、Test::Unit::TestCaseを継承したclassを作成します。
名前がtest_で始まるメソッドを作成しましょう。

require 'test/unit'

class TestJanken < Test::Unit::TestCase
  def test_janken
  end
end


次にジャンケンの判定部分をクラスにまとめます。

require 'test/unit'

class Janken
  def self.hantei(your_hand, com_hand)
    hands = ["g", "c", "p"]
    num = hands.index(your_hand)

    if hands[num - 2] == com_hand
      'あなたの勝ちです'
    elsif hands[num - 1] == com_hand
      'あなたの負けです'
    else
      '引き分けです'
    end
  end
end

class TestJanken < Test::Unit::TestCase
  def test_janken
  end
end



最後にtestメソッドにassert_equalを追加します。
assert_equal 期待される値A, テスト対象B
のように書き、A = Bであればテストを通過できます。
今回は全ての手の組み合わせと、勝ち負けの結果を記入します。

require 'test/unit'

class Janken
  def self.hantei(your_hand, com_hand)
    hands = ["g", "c", "p"]
    num = hands.index(your_hand)

    if hands[num - 2] == com_hand
      'あなたの勝ちです'
    elsif hands[num - 1] == com_hand
      'あなたの負けです'
    else
      '引き分けです'
    end
  end
end

class TestJanken < Test::Unit::TestCase
  def test_janken
    assert_equal '引き分けです', Janken.hantei("g", "g")
    assert_equal '引き分けです', Janken.hantei("c", "c")
    assert_equal '引き分けです', Janken.hantei("p", "p")
    assert_equal 'あなたの勝ちです', Janken.hantei("g", "c")
    assert_equal 'あなたの勝ちです', Janken.hantei("c", "p")
    assert_equal 'あなたの勝ちです', Janken.hantei("p", "g")
    assert_equal 'あなたの負けです', Janken.hantei("g", "p")
    assert_equal 'あなたの負けです', Janken.hantei("c", "g")
    assert_equal 'あなたの負けです', Janken.hantei("p", "c")
  end
end

それでは実行してみましょう。

f:id:fumiyaokabe:20180612101033p:plain
テスト結果。ジャンケンの判定は正しく行われていたようですね。
9 assertions, 0 failures, 100% passedと出ましたので、全てのケースにおいてテストを通過しました。



それでは間違ったコードを書いていた場合はどうなるのでしょうか。試してみました。

f:id:fumiyaokabe:20180612113925p:plain
1 failuresと表示され、途中で止まってしまう。
「"勝ち"のはずなのに"負け"になってますよ」と教えてくれます。