Ruby の test-unit で特定のテストだけ実行する
fluentd plugin を作ろうとしたところ、fluentd では test-unit でテストを書くことを推奨しているので test-unit でテストを書こうとしたんですが、ネット上に溢れている情報では test
メソッドを使って定義したテストの実行方法や rake task 経由で指定する方法について言及されているものが見つからなかったのでまとめてみました。
Fluentd core project strongly recommends to use test-unit as a unit test library.
test-unit の情報源
公式ページは http://test-unit.github.io/ で、テストケースの書き方については Test::Unit::TestCase のドキュメント を読むのが良さそうです。
日本語のページだと Test::Unitでテストを書く - Qiita がとても参考になります。
特定のテストの実行の仕方については test-unitで指定したテストだけ実行する方法 - Qiita が参考になります。自分のググり力が低いのか、英語だとこれだけの情報がまとまっているものは見つかりませんでした。
test-unit で定義した特定のテストを実行する方法
次のようなファイルを考えます。
require "test-unit"
class MyTest < Test::Unit::TestCase
def test_write
puts "test_write"
end
test "write" do
puts "write"
end
sub_test_case "with a certain option true" do
test "write" do
puts "with a certain option true: write"
end
test "try_write" do
puts "with a certain option true: try_write"
end
end
end
test_write だけ実行する
-n
オプションにメソッド名を指定します。
% ruby -I test /path/to/test.rb -v -n 'test_write'
Loaded suite /path/to/test
Started
MyTest:
test_write: test_write
.: (0.000288)
Finished in 0.00103 seconds.
-------------------------------------------------------------------------------------------
1 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-------------------------------------------------------------------------------------------
970.87 tests/s, 0.00 assertions/s
全ケースの test “write” だけ実行する
-n
オプションに test: DESCRIPTION
の形式で値を指定します。
% ruby -I test /path/to/test.rb -v -n 'test: write'
Loaded suite /path/to/test
Started
MyTest:
test: write: write
.: (0.000280)
with a certain option true:
test: write: with a certain option true: write
.: (0.000289)
Finished in 0.00118 seconds.
-------------------------------------------------------------------------------------------
2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-------------------------------------------------------------------------------------------
1694.92 tests/s, 0.00 assertions/s
これは test
メソッドを使ってテストを定義すると test: DESCRIPTION
の形式でメソッドが定義されるからです。
特定のケースだけ実行する
-t
オプションに TESTCASE::SUB_TESTCASE_DESCRIPTION
の形式で値を指定します。
% ruby -I test /path/to/test.rb -v -t 'MyTest::with a certain option true'
Loaded suite /path/to/test
Started
MyTest:
with a certain option true:
test: try_write: with a certain option true: try_write
.: (0.000452)
test: write: with a certain option true: write
.: (0.000198)
Finished in 0.001285 seconds.
-------------------------------------------------------------------------------------------
2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-------------------------------------------------------------------------------------------
1556.42 tests/s, 0.00 assertions/s
これは sub_test_case
メソッドを使うと name
メソッドでこのような形式の値を返すクラスが定義されるからです。-t
オプションを指定した場合は match_test_case_name
メソッドによってマッチするかの判定が行われ、これに name
メソッドが使われます。
なお、-n
オプションも -t
オプションも /
で括ることで正規表現を使うことができるので、今回のケースでは次のように簡略化して書くこともできます。
% ruby -I test /path/to/test.rb -v -t '/with a certain option true/'
Loaded suite /path/to/test
Started
MyTest:
with a certain option true:
test: try_write: with a certain option true: try_write
.: (0.000639)
test: write: with a certain option true: write
.: (0.000236)
Finished in 0.001906 seconds.
-------------------------------------------------------------------------------------------
2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-------------------------------------------------------------------------------------------
1049.32 tests/s, 0.00 assertions/s
rake task で特定のテストを実行する方法
TESTOPTS
環境変数に test-unit のオプションを指定すれば良いです。ただし、-n 'test: write'
のようにスペースを空けるとファイル名として認識して File does not exist というエラーになるので注意してください。
よって、test: write
を実行するには次のどちらかのように指定することになります。
rake test TESTOPTS="-n'test: write'"
rake test TESTOPTS="--name='test: write'"