JavaのライブラリのテストをJRuby+minitestで書く
お前は何と戦っているんだ感が半端ないですが、タイトルの通りJavaで書いたライブラリのテストをJRuby+minitestで書いてみました。
テストを書く対象のライブラリは、よくある(?)行列演算を行うやつです。
例としてMyMatrixLib.jar (net.rkmathi.lib.MyMatrixLib)
という名前にしてみます。
JRuby, minitestのインストール
rbenvを使っているので、それ経由で入れました。
$ rbenv install -l | grep jruby ... jruby-1.7.16 jruby-1.7.16.1 jruby-9.0.0.0-dev jruby-9000-dev ...
jruby-1.7.16.1にしました。
$ rbenv install jruby-1.7.16.1
テスト書くディレクトリに移動して、rbenv local
でjrubyを使うようにします。
$ cd /path/to/test_directory $ rbenv local jruby-1.7.16.1 $ rbenv rehash $ jruby --version jruby 1.7.16.1 (1.9.3p392) 2014-10-28 4e93f31 on Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b17 +jit [darwin-x86_64]
minitestのインストールをします。
$ jruby -S gem install minitest
ライブラリのJARを持ってくる
$ cd /path/to/test_directory $ cp /path/to/MyMatrixLib.jar .
JRuby+minitestでテストを書く
とりあえず、get()とplus()とminus()のテストを書いてみるとこうなります。
require 'minitest' require 'minitest/autorun' require 'java' require_relative './MyMatrixLib.jar' import 'net.rkmathi.lib.MyMatrixLib' class TestMyMatrixLib < Minitest::Test def setup @d1 = rand(1000.0) @d2 = rand(1000.0) @m1 = MyMatrixLib.new(3, 2, @d1) # 3x2ですべての要素が@d1の行列を生成 @m2 = MyMatrixLib.new(3, 2, @d2) # 3x2ですべての要素が@d2の行列を生成 end # get(r, c) => double: 行列のr行c列目の要素を取得 def test_get each_assert_get @m1, @d1 each_assert_get @m2, @d2 end # plus(matrix) => MyMatrix: 行列のそれぞれの要素を足した行列を生成 def test_plus d_res = @d1 + @d2 m_res = @m1.plus(@m2) # @m1と@m2のそれぞれの要素を足した結果の行列 each_assert_get m_res, d_res end # minus(matrix) => MyMatrix: 行列のそれぞれの要素を引いた行列を生成 def test_minus d_res = @d1 - @d2 m_res = @m1.minus(@m2) # @m1と@m2のそれぞれの要素を引いた結果の行列 each_assert_get m_res, d_res end private # 行列の各要素をそれぞれgetするのが面倒なのでメソッド化 def each_assert_get(m, d) for r in 0...m.get_row_dimension do for c in 0...m.get_column_dimension do assert_equal m.get(r, c), d end end end ... end
と、こんな感じで書くことができます。
ちなみにJUnitだと...
public class MyMatrixLibTest { @Before public void setUp() throws Exception { MyMatrixLib d1 = Math.random() * 1000.0; MyMatrixLib d2 = Math.random() * 1000.0; MyMatrixLib m1 = new MyMatrixLib(3, 2, d1); MyMatrixLib m2 = new MyMatrixLib(3, 2, d2); } @Test public void testGet() { eachAssertGet(m1, d1); eachAssertGet(m2, d2); } @Test public void testPlus() { double d_res = d1 + d2; MyMatrixLib m_res = m1.plus(m2); eachAssertGet(m_res, d_res); } @Test public void testMinus() { double d_res = d1 - d2; MyMatrixLib m_res = m1.minus(m2); eachAssertGet(m_res, d_res); } private void eachAssertGet(MyLibMatrix m, double d) { for (int row = 0; row < m.getRowDimension(); row++) { for (int column = 0; column < m.getRowDimension(); column ++) { assertEquals(m.get(row, column), d); } } } }
簡単な演算のテスト部分しか比較しませんでしたが、書いてて楽には思えました。
ですが、JRubyを書いていると文法とか変数の型をミスった時に吐かれる例外がよくわからないことになることもあるので、わざわざJRubyでテスト書くのは微妙かも...