Code Journey

30代未経験からプログラミング挑戦中(追うものは追われる者に勝る)

Ruby標準のテスティングフレームワークTest::Unitで簡単なテストを書く方法

はじめに

私は現在、フィヨルドブートキャンプにて未経験からプログラミング学習をしているものになります。

この記事は、自分自身が学習したことをまとめ、アウトプットすることを目的として書いていますので、間違いがある可能性がありますのでご注意ください。

今回は、Rubyのテスティングフレームワークtest-unitを使って簡単なテストをやる方法を学んだのでアウトプットします。

インストール

$ gem install test-unit

使い方

  • まずTest::Unit::TestCaseを継承したクラスを用意する 例
class TestCat < Test::Unit::TestCase
  • test_xxxというメソッドを定義するとそのメソッドがテストの実行対象になる
def test_xxx
  • assert_equal 期待値, 実際の値で実行結果を検証できる(アサーション) 一致すればテストがパスし、一致しない場合はテストが失敗となる
assert_equal (期待する結果),(テスト対象)
  • 1つのテストメソッド内にassert_equalを複数書くこともできる しかし、原則として1テストメソッドにつき1アサーションとするのが望ましい

  • $ ruby ファイル名で実行すればOK

実際にやってみた

require 'test/unit'

class Cat
  def self.morning_greeting
    'はよ起きてごはんをよこせ!'
  end
end

class TestCat < Test::Unit::TestCase
  def test_morning_greeting
    assert_equal 'はよ起きてごはんをよこせ!', Cat.morning_greeting
  end
end

実行結果 test.rb

❯ ruby test.rb
Loaded suite test
Started
.
Finished in 0.000172 seconds.
-----------------------------------------------------------------------------------------------------------------------------------
1 tests, 1 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-----------------------------------------------------------------------------------------------------------------------------------
5813.95 tests/s, 5813.95 assertions/s

1つのテストメソッドに複数書く場合

require 'test/unit'

class Cat
  def self.morning_greeting
    'はよ起きてごはんをよこせ!'
  end
end

class TestCat < Test::Unit::TestCase
  def test_morning_greeting
    assert_equal 'はよ起きてごはんをよこせ!', Cat.morning_greeting
  end

    def test_calc
    assert_equal 'Kinako', 'Kina' + 'ko'
    assert_equal 'Shiratama', 'Shira' + 'tama'
  end
end

実行結果

❯ ruby test.rb
Loaded suite test
Started
..
Finished in 0.000201 seconds.
-----------------------------------------------------------------------------------------------------------------------------------
2 tests, 3 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-----------------------------------------------------------------------------------------------------------------------------------
9950.25 tests/s, 14925.37 assertions/s

TestCase毎ごとに呼ばれるstartupやshutdownなどが使える

require 'test/unit'

class Cat
  def self.morning_greeting
    'はよ起きてごはんをよこせ!'
  end
end

class TestKedama < Test::Unit::TestCase
    class << self
    # テスト群の実行前に呼ばれる
    def startup
      p :_startup
    end

    # テスト群の実行後に呼ばれる
    def shutdown
      p :_shutdown
    end
  end

  def setup
    p '毎回テスト前に呼ばれる'
  end

  # テスト後の状態確認とかに使える
  def cleanup
    p 'テストがpassedになった場合に、テスト実行後に呼ばれる'
  end

  def teardown
    p '毎回テスト実行後に呼ばれる'
  end

  def test_morning_greeting
    assert_equal 'はよ起きてごはんをよこせ!', Cat.morning_greeting
  end

    def test_calc
    assert_equal 'Kinako', 'Kina' + 'ko'
    assert_equal 'Shiratama', 'Shira' + 'tama'
  end
end

実行結果

❯ ruby test.rb
Loaded suite test
Started
:_startup
"毎回テスト前に呼ばれる"
"テストがpassedになった場合に、テスト実行後に呼ばれる"
"毎回テスト実行後に呼ばれる"
."毎回テスト前に呼ばれる"
"テストがpassedになった場合に、テスト実行後に呼ばれる"
"毎回テスト実行後に呼ばれる"
.:_shutdown

Finished in 0.000465 seconds.
-----------------------------------------------------------------------------------------------------------------------------------
2 tests, 3 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-----------------------------------------------------------------------------------------------------------------------------------
4301.08 tests/s, 6451.61 assertions/s

失敗させると

require 'test/unit'

class Cat
  def self.morning_greeting
    'はよ起きてごはんをよこせ!'
  end
end

class TestCat < Test::Unit::TestCase
    class << self
    # テスト群の実行前に呼ばれる
    def startup
      p :_startup
    end

    # テスト群の実行後に呼ばれる
    def shutdown
      p :_shutdown
    end
  end

  def setup
    p '毎回テスト前に呼ばれる'
  end

  # テスト後の状態確認とかに使える
  def cleanup
    p 'テストがpassedになった場合に、テスト実行後に呼ばれる'
  end

  def teardown
    p '毎回テスト実行後に呼ばれる'
  end

  def test_morning_greeting
    assert_equal 'はよ起きてごはんをよこせ', Cat.morning_greeting
  end

    def test_calc
    assert_equal 'Kinako', 'Kina' + 'k'
    assert_equal 'Shiratama', 'Shira' + 'tam'
  end
end

実行結果

❯ ruby test.rb
Loaded suite test
Started
:_startup
"毎回テスト前に呼ばれる"
F
===================================================================================================================================
Failure: test_calc(TestCat)
test.rb:40:in `test_calc'
     37:   end
     38: 
     39:     def test_calc
  => 40:     assert_equal 'Kinako', 'Kina' + 'k'
     41:     assert_equal 'Shiratama', 'Shira' + 'tam'
     42:   end
     43: end
<"Kinako"> expected but was
<"Kinak">

diff:
? Kinako
===================================================================================================================================
"毎回テスト実行後に呼ばれる"
"毎回テスト前に呼ばれる"
F
===================================================================================================================================
Failure: test_morning_greeting(TestCat)
test.rb:36:in `test_morning_greeting'
     33:   end
     34: 
     35:   def test_morning_greeting
  => 36:     assert_equal 'はよ起きてごはんをよこせ', Cat.morning_greeting
     37:   end
     38: 
     39:     def test_calc
<"はよ起きてごはんをよこせ"> expected but was
<"はよ起きてごはんをよこせ!">

diff:
? はよ起きてごはんをよこせ!
===================================================================================================================================
"毎回テスト実行後に呼ばれる"
:_shutdown

Finished in 0.00557 seconds.
-----------------------------------------------------------------------------------------------------------------------------------
2 tests, 2 assertions, 2 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
-----------------------------------------------------------------------------------------------------------------------------------
359.07 tests/s, 359.07 assertions/s

テストが失敗しているのでcleanupが呼ばれていないことがわかります。

他にもインスタンスメソッドはたくさん存在する

Module: Test::Unit::Assertions -Instance Method Summary-