まず初めに
課題で「ジャンケンのプログラムをtest/unitを使ってテストしろ。」と出され、テストコード自体初めて聞いたので、自分用のメモとして記載します。
動作環境は以下の通り。
mac
Ruby 2.6.5
test/unit 3.3.6
達成したいこと
ジャンケンのプログラムを、「test/unit」を使用して、テストする。
test/unitとは
そもそも、テストコードとは、書いたプログラムのロジックが、想定通りの動きをしているか、確認するためのプログラムです。
test/unitはRuby用のテストフレームワークで、元々は標準搭載されていたらしいです。
tesu/unit自体のインストールはこちらを参照してください。
test/unitの基本的な使い方
前提として、ver.によって多少異なるので、ご了承ください。
基本的な構文は以下の通り。
require 'test/unit'
class [クラス名] < Test::Unit::TestCase
end
まずはこのフレームワークを使用するために'test/unit'
をrequire
します。
つぎに、Test::Unit::TestCase
を継承したclassを作成します。
RubyではTest::Unit::TestCase
を継承することでそのクラスはテスト実行ファイルになります。
require 'test/unit'
class [クラス名] < Test::Unit::TestCase
def test_[メソッド名]
foo = "hoge"
assert_equal("hoge", foo)
end
end
テストの処理は上記の通りです。
メソッドを作成し、そちらにテストしたいプログラムを書きます。メソッド名はtest_
から始めるのがルールです。このメソッド内では、以下の書式でチェックメソッドを書きます。(チェックメソッドは、他にもあります)
assert_equal(想定の値, 変数やメソッド等)
assert_equal
では、変数の値やメソッドの返り値が想定のものと一致することを確認します。
こちらで簡単なチュートリアルは終わりですが、もっとデフォルトで使用できるメソッドなどあるので、リファレンスを参照してみてください。
解決方法
それでは、達成条件の解決方法を以下に記載します。
まずですが、ジャンケンのプログラムを先に書いてしまいます。
(あまり、スマートなプログラムではないですが、ご容赦ください)
標準入力でgかcかpを入力したら、ジャンケンの結果が出力される仕組みです。
player = gets.chomp
if player == "g"
player = "グー"
elsif player == "c"
player = "チョキ"
elsif player == "p"
player = "パー"
end
com = rand(3)
if com == 0
com = "グー"
elsif com == 1
com = "チョキ"
else
com = "パー"
end
if player == com
res = "引き分け"
elsif (player == "グー" && com == "チョキ") || (player == "チョキ" && com == "パー") || (player == "パー" && com == "グー")
res = "あなたの勝ち"
else
res = "あなたの負け"
end
puts "あなたは#{player}、私は#{com}、#{res}です。"
今回の場合は、player
とcom
の2つの変数の値が決まったときに正しい結果が表示されるかをテストするので、テストするのは以下の部分です。
if player == com
res = "引き分け"
elsif (player == "グー" && com == "チョキ") || (player == "チョキ" && com == "パー") || (player == "パー" && com == "グー")
res = "あなたの勝ち"
else
res = "あなたの負け"
end
puts "あなたは#{player}、私は#{com}、#{res}です。"
今回は、上記の勝敗を判定する処理をクラスにまとめます。
class Janken
def self.judge(player,com)
if player == com
res = "引き分け"
elsif (player == "グー" && com == "チョキ") || (player == "チョキ" && com == "パー") || (player == "パー" && com == "グー")
res = "あなたの勝ち"
else
res = "あなたの負け"
end
return "あなたは#{player}、私は#{com}、#{res}です。"
end
end
ジャンケンの勝敗の処理をクラスにまとめました。
そうしたら、テスト処理の方を書きます。
require 'test/unit'
class Test_Janken < Test::Unit::TestCase
def test_janken
assert_equal('あなたはグー、私はグー、引き分けです。', Janken.judge("グー","グー"))
assert_equal('あなたはチョキ、私はチョキ、引き分けです。', Janken.judge("チョキ","チョキ"))
assert_equal('あなたはパー、私はパー、引き分けです。', Janken.judge("パー","パー"))
assert_equal('あなたはグー、私はチョキ、あなたの勝ちです。', Janken.judge("グー","チョキ"))
assert_equal('あなたはチョキ、私はパー、あなたの勝ちです。', Janken.judge("チョキ","パー"))
assert_equal('あなたはパー、私はグー、あなたの勝ちです。', Janken.judge("パー","グー"))
assert_equal('あなたはグー、私はパー、あなたの負けです。', Janken.judge("グー","パー"))
assert_equal('あなたはチョキ、私はグー、あなたの負けです。', Janken.judge("チョキ","グー"))
assert_equal('あなたはパー、私はチョキ、あなたの負けです。', Janken.judge("パー","チョキ"))
end
end
ジャンケンの勝敗のパターンの全9通りをassert_equal
で検証するという感じです。
これをジャンケンの処理を合体させます。
以下のコードが最終的なものになります。
require 'test/unit'
class Janken
def self.judge(player,com)
if player == com
res = "引き分け"
elsif (player == "グー" && com == "チョキ") || (player == "チョキ" && com == "パー") || (player == "パー" && com == "グー")
res = "あなたの勝ち"
else
res = "あなたの負け"
end
return "あなたは#{player}、私は#{com}、#{res}です。"
end
end
class Test_Janken < Test::Unit::TestCase
def test_janken
assert_equal('あなたはグー、私はグー、引き分けです。' ,Janken.judge("グー","グー"))
assert_equal('あなたはチョキ、私はチョキ、引き分けです。' ,Janken.judge("チョキ","チョキ"))
assert_equal('あなたはパー、私はパー、引き分けです。' ,Janken.judge("パー","パー"))
assert_equal('あなたはグー、私はチョキ、あなたの勝ちです。' ,Janken.judge("グー","チョキ"))
assert_equal('あなたはチョキ、私はパー、あなたの勝ちです。' ,Janken.judge("チョキ","パー"))
assert_equal('あなたはパー、私はグー、あなたの勝ちです。' ,Janken.judge("パー","グー"))
assert_equal('あなたはグー、私はパー、あなたの負けです。' ,Janken.judge("グー","パー"))
assert_equal('あなたはチョキ、私はグー、あなたの負けです。' ,Janken.judge("チョキ","グー"))
assert_equal('あなたはパー、私はチョキ、あなたの負けです。' ,Janken.judge("パー","チョキ"))
end
end
結果は、、
Loaded suite test
Started
.
Finished in 0.000811 seconds.
--------------------------------------------------------------------------------
1 tests, 9 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
--------------------------------------------------------------------------------
1233.05 tests/s, 11097.41 assertions/s
問題なく、テストできました。
リファレンス
test/unitライブラリ - doc.ruby-lang.org