コメント行でUnitテストが出来るようにするスクリプト
http://d.hatena.ne.jp/walf443/20060710/1152551319 のアイディアを部分的に実装してみた。
一時ファイルに出力して云々とかはしてないのでまだちゃんとした体裁にはなっていないのですが。
今のところの問題は
- クラスが一つしか認識できないこと
- setup()メソッドやteardown()メソッドが書けない事
といった感じでまだダメダメなんですがなんかレスポンスがもらえるとうれしいので晒しておきます。
id:kikainekoさんのrubytokにインスパイアされて書いたのですが、コードは一から書き直したので全然違うものとなってます。
実際のコードがこんなんで、
class Hoge # Test: # assert_equal("foo", Hoge.new.foo) def foo "foo" end # Test: # assert_not_equal("foo", Hoge.new.bar) def bar "bar" end end
これを実行するとこんな感じに出力されます。
walf443@colinux:doctest% ruby rubytest.rb sample.rb require 'test/unit' require 'sample' class TestHoge < Test::Unit::TestCase def test_foo assert_equal("foo", Hoge.new.foo) end def test_bar assert_not_equal("foo", Hoge.new.bar) end end
今のところは出力結果をパイプでrubyに渡してやればテストを実行できます。
walf443@colinux:doctest% ruby rubytest.rb sample.rb | ruby
Loaded suite -
Started
..
Finished in 0.031695 seconds.2 tests, 2 assertions, 0 failures, 0 errors
ソースはこんな感じです。
#!/usr/bin/env ruby unless ARGV.size == 1 puts "Usage: ruby #{__FILE__} FILENAME" exit end filename = ARGV.shift lines = "" File.open(filename) do |file| lines = file.readlines end COMMENT_REGEX = /^#/ DEFINE_METHOD_REGEX = /^def\s(.+?)\b/ DEFINE_CLASS_REGEX = /^class\s(.+?)\b/ TEST_POINTER_REGEX = /^# Test:\s*$/i TEST_COMMENT_REGEX = /^#>/ lines = lines.map {|i| i.strip!}.select {|i| (i =~ COMMENT_REGEX ) || (i =~ DEFINE_METHOD_REGEX) || (i =~ DEFINE_CLASS_REGEX) } test_lines = [] test_lines << "require 'test/unit'\n" test_lines << "require '#{filename.sub(/\.rb/, "")}'\n" test_lines << "\n" class_lines = [] method_lines = [] method_flag = false class_flag = true class_name = nil lines.each do |line| if line =~ DEFINE_CLASS_REGEX class_flag = true class_name = "Test#{$1}" next end if line =~ TEST_POINTER_REGEX method_flag = true next end if method_flag if line =~ DEFINE_METHOD_REGEX method_flag = false line = " def test_#{$1}" class_lines << line << method_lines << " end\n" << "\n" method_lines = [] else method_lines << line.sub("# ", " ") end end end class_name ||= "DocTestTestCase" test_lines << "class #{class_name} < Test::Unit::TestCase\n" << class_lines << "end\n" puts test_lines
テストを推奨のクセにTestを全く行なってないことがバレバレなつくりになってます。
メソッドは「def 〜」と出てくるだけでよいのですが、クラスはどういうところで終わりにしていいのかが難しいところです。