脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

rubyのデフォルトのUnit testの使い方

Rubyにデフォルトで入っているテストフレームワークのUnit testの使い方です。
ちなみに以前書きましたがrubyのデフォルトのテストフレームワークは各versionで中身が違います。portaltan.hatenablog.com

使い方

準備

unit.rb
require 'test/unit'

class SampleTest < Test::Unit::TestCase

end

1. まずはテストフレームワークを使用するために'test/unit'をrequireします
2. つぎにTest::Unit::TestCaseを継承したclassを作成します

  • rubyではTest::Unit::TestCaseを継承することで自動でそのクラスはテスト実行ファイルになります

これで基本的な設定は完了です。現時点で実行すると以下のようになります。

$ ruby unit.rb
Run options:

# Running tests:

Finished tests in 0.002284s, 0.0000 tests/s, 0.0000 assertions/s.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips

ruby -v: ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]


テストの作成

次に実際のテスト処理を書きます

require 'test/unit'

class SampleTest < Test::Unit::TestCase

  def test_sample1
    foo = '111'
    assert_equal('111', foo)
  end

end

1. test_*という名前のメソッドを作成します。

  • 上のほうでTest::Unit::TestCaseを継承したクラスは自動でテスト実行ファイルになると書きましたが、実際はその中のtest_*というメソッドが、自動で実行されるテストになります。

2. メソッド内でチェックメソッドを書きます。書式は以下です。

  assert_equal(予想される値, 変数やメソッド等)
  • assert_equalでは変数の値やメソッドの返り値が予想と一致することを確認します。

上記を実行すると・・・

$ ruby unit.rb
Run options:

# Running tests:

Finished tests in 0.004152s, 240.8293 tests/s, 240.8293 assertions/s.
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

ruby -v: ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
  • 先ほどは0だったtestsとassertionsが1件増えました。

予想とは違う場合は以下のようになります。

メソッド
  def test_sample1
    foo = '111'
    assert_equal('111', foo)
  end
実行結果
]$ ruby unit.rb
Run options:

# Running tests:

[1/1] SampleTest#test_sample1 = 0.00 s
  1) Failure:
SampleTest#test_sample1 [unit.rb:17]:
<"222"> expected but was
<"111">.

Finished tests in 0.003316s, 301.5818 tests/s, 301.5818 assertions/s.
1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
  • failuresが1件増えています。


テストの前処理・後処理

class SampleTest < Test::Unit::TestCase
  @@i = 0

  def setup
    @@i += 1
    puts "\r\nstart test #{@@i}========================================"
  end

  def teardown
    puts "\r\nfinish test #{@@i}========================================"
  end

  def test_sample1
    assert_equal('111', foo)
  end

  def test_sample2
    assert_equal('222', foo)
  end

end
実行結果
$ ruby unit.rb
Run options:

# Running tests:

[1/2] SampleTest#test_sample1
start test 1========================================

finish test 1========================================
[2/2] SampleTest#test_sample2
start test 2========================================

finish test 2========================================
 = 0.00 s
  1) Failure:
SampleTest#test_sample2 [unit.rb:23]:
<"222"> expected but was
<"111">.

Finished tests in 0.003935s, 508.2782 tests/s, 508.2782 assertions/s.
2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

ruby -v: ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
  • テスト毎に前処理・後処理が実行されているのがわかります。


Tips

動的ディスパッチ

Test::Unitはめいめい規則を使ってテストメソッドを判別しているが、TestCase自身が自身のpublicメソッドをチェックして名前がtestではじまるメソッドを選択している。

method_names = public_instance_methods(true)
tests = method_names.delte_if{|method_name| method_name !~ /^test./*}

この配列を__send__()を使って後で実行している。

他のチェックメソッド

正規表現
assert_match(/予想される正規表現/, チェックしたい値)
nilチェック
assert_nil(チェックしたい値)






今までは最初に使ったのがrspecなんでrspecを使うことが多かったですが、意外とデフォルトのUnit testも使いやすいかもしれない。