読者です 読者をやめる 読者になる 読者になる

Ruby Testing on Kikaineko

http://d.hatena.ne.jp/kikaineko/20060524#p1 より。

what is "Ruby Testing on Kikaineko"?(略してrubytok)

Rubyのコメント部分からコードを抜き出し、テストとして実行するツールです。pythonのDocTestをご存知であれば、あれを想像してください。rubytokはDocTestにヘビーインスパイアされたものです。
From:
http://d.hatena.ne.jp/kikaineko/20060524#p1

ということでプログラムにテストのコードを埋め込めるようにしたツールのようです。Rubyみたいにプログラミングが楽だとソースコードとテストのファイルが別々であるだけでテストをやる気が萎えてしまうので良いなと思いました。また、ソースコード読む際にもWhatを具体的に表現することになるので、うれしいですね。

どうやってやってるのかなとソース眺めてみたら、特定の形式の行を正規表現でかき集めてきて、それをTempfileを使ってRubyプログラムの体裁をした一時ファイルとして作成し、それを実行するといった感じでした。

Tempfileを途中で拡張しているのですが、requireじゃなくてloadを使えば拡張する必要はないのではないかと思いました。

テスト部分が自前で実装していらっしゃるのですが、個人的には今までの資産を生かしてTest::Unitのメソッドを自由に使えた方が良いなと思います。

読みやすくするために、頻度の高いassert_equalなどにマクロ的な表記方法を設ける*1のは良いと思います。ただ基本的には普通のRubyの方法で書けた方が良いと思います。

# foo.rb

class Foo
  #> def setup
  #>   @obj = Foo.new
  #> end
  #> def teardown
  #>   @obj.close
  #> end

  # just return str.
  # Test:
  #  assert_equal("hoge", @obj.hoge("hoge"))
  #  @obj.hoge("foo") #=> "foo"
  def hoge(str)
    str
  end
end

とかすると、

require 'test/unit'
require 'foo'

class TestFoo < Test::Unit::TestCase
  def setup
    @obj = Foo.new
  end
  def teardown
    @obj.close
  end
  def test_hoge
     assert_equal("hoge", @obj.hoge("hoge"))
     assert_equal("foo", @obj.hoge("foo"))
  end
end

という感じの一時ファイルを吐き出して実行させるといった感じになればRDocで出力したときに自然に読めそうで良いかなと思いました。

コメント行で、#>から始まるものをテストコードとみなす他にも、Test:からdef hogeまでをUnitテストのテストコードとみなして、自動的にdef test_hogeとかにするとかできると重複したことを書く必要もないし、RDocで見たときも自然に見えてよいのではないかと思ったり*2。欲張るなら先ほど言ったように一番よく使うassert_equalにマクロ的な書き方を用意して、actual #=> expectedと書けたら良いなぁと思いました。

何とかできそうな気がしなくもないけどまだ試してないです。

*1:actual #=> expected といった感じとか

*2:RDocの書き方そのものをしっかり把握してないのでもっと適切な書き方がありそうですが。