前回minitestのオススメ設定を紹介させていただきましたが
アサーションをどう記述するかに関しては、関連するgemが多すぎて記事としてまとめられませんでしたので
別記事として紹介させていただきます
どの様にテストを記述したいのか、という用途別で敢えて分類を行うならば
下の4択のいずれかなのではないかな、と思います
- assert_equalを拡張していく、power assertを取り込んでいく
- rspecに近づける
- must_equalに寄せていく
- shouldaに近づける
以前からshouldaを使ってテストを記述してきた人じゃないなら、shouldaの書式に近づける意味は無いので、実質三択ですがそれぞれの用途別にインストールするgemを紹介させていただきましょう
今回は、動作確認は、以下の環境でチェックしています
- rails 4.1.8
- minitest 5.4.0
assert_equalで拡張を続ける
test/unitから脈々と受け継がれているassert_equalでテストを記述したいという場合は、こちらを使うべきでしょう
利点としては、次のようなものが挙げられるでしょうか
- 他の言語でも、スタンダードで使われている書式なので文化的にも学習コストが低い
- minitestの標準の書式の一つ
実際の書式としては、条件が真であるかというのを調べるassert、条件が偽であるかを調べるrefute関数と、その派生関数を使ってテストを行います
assert true # 実行結果が真なのかをチェック
assert_equal true, true # 2つの値が同じかどうかをチェック
assert_empty [] # 中身が空かどうかをチェック
refute false # 実行結果が偽なのかをチェック
refute_equal true, false # 実行結果が同じ値にならないのをチェック
インストールするときは以下をコピペが楽でしょうか
group :test do
gem 'minitest-ar-assertions', "0.1.1", :require => 'minitest_activerecord_assertions'
gem "minitest-power_assert", "0.0.3"
end
minitest-ar-assertions
assert_association Comment, :has_many, :likes, :as => :likeable
assert_association Post, :has_many, :likes => :as => :likeable
assert_association Like :belongs_to, :likeable
active_recordのhas_oneやhas_many、belongs_to等の関連を簡潔に書ける拡張です。
rspecでも同様の機能がありますね
minitest-power_assert
it "金額が指定通り" do
assert { @amount == 100 }
end
書式は 「assert { テスト書式 }」という感じで、テストを記述していくだけでいいです。
ブロックの実行結果の真偽でテストの実行結果をチェックします
テストに失敗をすると、下の様に実行結果の内部の変数それぞれを分解して表示してくれるので、失敗したテストの中身を見るためにブレークポイントを貼ったりinspectメソッドで各変数を表示して原因を探さなくて良くなります
assert { @amount == 100 }
| |
| false
55
オブジェクトの場合も、inspectメソッドを使った時の様に内部を表示してくれます
さらに詳しくはテスト用ライブラリ power-assertを参照していただくと分かりやすいのですが
Groovy から出てきたpower assertと同等の機能を実現するgemですね。
- 既存のassertの文法にかなり自然に融和して
- 書式が簡潔で覚えやすい
- エラーを今までよりも詳細に表示してくれる
という感じなので、基本power assertの書式に従って「minitest-ar-assertions」の様に、power assertの力を借りない方が簡潔に書ける場合のみ、その力を借りるというスタイルが良いと思います
must_equalに寄せていく
minitestには下の書式のように、shouldではなく、mustでオブジェクト間をつないでいくメソッドが標準で備わっています
true.must_equal true # 2つの値が同じかどうかをチェック
true.wont_equal false # 2つの値が同じでないかをチェック
下の2つのgemはそれに対して書式の拡張を行っていくものですね
minitest-great_expectations
書式に、配列やハッシュのパターンマッチ機能を追加します
下の書式の様に記述しますが、一目で実用性が実感できます
[1, 2, 3].must_equal_contents [3, 2, 1]
[1, 2, 3].must_include_all [1, 2]
{ :a => 1, :b => 2 }.must_equal_hash( { :b => 2, :a => 1 } )
rspecに近づける
今まで慣れ親しんだrspecに出来るだけ書式を近づけたい、という場合にはこちらの書式を使うのが一番よいでしょう
※ 本当はminitest-should_syntaxの方が便利なのですが、最新のrails環境に追随できていないまま2年更新が止まっていました
minitest-shouldify
rspecのshouldに似たshould_equalなどのメソッドを生やします
"bar".should_equal "bar"
"bar".should_not_equal "baz"
minitest-spec-expect
rspecのexpect関数に類似した仕様のexpect関数を追加します
expect(1 + 1).to_equal 2 # 値が一致しているかどうかをチェック
expect(1 + 1).to_not_equal 3 # 一致していないかをチェック
おまけ: context関数の作成
describeの替わりにcontextが使いたい場合には
これ動かなかったので、test_helper.rbに
自前でモンキーパッチングを行って、contextメソッドは追加しました
minitest-spec-contextというgemもあるのですが、2年ほど更新もされておらず、現在の環境では動かなくなっていました
module Kernel
alias_method :context, :describe
end
shouldaに近づける
これはshouldaに記法を寄せるためのgemですね
一応、簡単にサンプルを出させていただきますが
実際のコードはこんな感じになります
context "Something else" do
setup do
@something = "nothing"
end
should "be nothing" do
assert_equal "nothing", @something
end
end
rspecの場合は次の3つの関数で文脈を作りますが
- describe
- before
- it
同じものを次の3つで行っている感じですね
- context
- setup
- should
正直、既にshouldaに慣れている人以外には
このスタイルの使い道は見当たらないのではないでしょうか
まとめ
さて、4種類、書式を紹介しましたが
私の方では、現状はassert equalとpower assertを併用しながら、簡潔に書ける方をケースバイケースで使い分けています
どれを選ぶかは本当に好みで決まるので、パッと見て気に入ったものから順番に試していくのがいいでしょう