From: Kouhei Sutou Date: 2014-01-26T14:17:25+09:00 Subject: [ruby-list:49742] Re: test-unitで使用するテストケースを動的に生成したい 須藤です。 In <920557.9381.qm@web100205.mail.kks.yahoo.co.jp> "[ruby-list:49741] Re: test-unitで使用するテストケースを動的に生成したい" on Sat, 25 Jan 2014 14:25:47 +0900 (JST), 古川大輔 wrote: > ただ、ファイルを作るたびにクラス定義を書かないといけないのがdryでない感じなのですけど、ここはしょうがないのでしょうか? なるほど、複数のブラウザで動かしたいテストがたくさんあるんで すね。 > 例えばこの後 test_add.rbを作ると > # test_add.rb > module AddTests >  def test_add1 >    STDERR.puts "[test]%s with %s"%['add1',browser.to_s] >  end > end > class AddWithBrowser1 < Browser1Test >  include AddTests > end > class AddWithBrowser2 < Browser2Test >  include AddTests > end > となって、うしろのクラス宣言を毎回ブラウザの数だけ書かないといけないのはなんとかならないの?というふうに感じています。 たしかにそうですね。 参考までに、私ならこうするというのを説明します。 私は、このケースのようにほとんどのテストをいろんなパターンで 動かしたいときは、パターンを環境変数で指定して、テストをN回動 かしています。各テストに対するパラメーターではなく、テスト全 体に対するパラメーターのように感じるので、テスティングフレー ムワークのレイヤーで頑張るのではなく、テストを実行するレイヤー で頑張るのがよいように感じます。 テストの実行結果がN回出てくるというのが気になると言えば気に なるのですが、ブラウザー毎に独立していると考えてこういう構成 を選んでいるならそんなにおかしくない気もします。 一方、ブラウザー毎にテスト結果がまとまるので、どのブラウザー で動かなくなっているかがわかりやすくなって、そんなに悪くない んじゃないかという気もします。 実装例です。まず、テストはいつも通り書きます。ブラウザーを選 ぶところは環境変数の値を使って適切なブラウザーを決めます。 test_browser.rb: -- require "test-unit" class BaseTest < Test::Unit::TestCase def browser browser_env = ENV["BROWSER"] case browser_env when "browser1", nil create_browser1 when "browser2" create_browser2 else raise "invalid browser: <#{browser_env.inspect}>" end end def create_browser1 "browser1" end def create_browser2 "browser2" end end class AddTest < BaseTest def test_add1 STDERR.puts "[test]%s with %s"%[__method__,browser.to_s] end end class SearchTest < BaseTest def test_serach1 STDERR.puts "[test]%s with %s"%[__method__,browser.to_s] end end -- テストを実行するところでブラウザーを指定します。Rakefileなら こんな感じです。 Rakefile: -- task :default => :test def run_test(env) sh(env, RbConfig.ruby, "test_browser.rb") end task :test do run_test({"BROWSER" => "browser1"}) run_test({"BROWSER" => "browser2"}) end -- -- % rake {"BROWSER"=>"browser1"} /usr/bin/ruby2.0 test_browser.rb Loaded suite test_browser Started [test]test_add1 with browser1 .[test]test_serach1 with browser1 . Finished in 0.007777236 seconds. 2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 100% passed 257.16 tests/s, 0.00 assertions/s {"BROWSER"=>"browser2"} /usr/bin/ruby2.0 test_browser.rb Loaded suite test_browser Started [test]test_add1 with browser2 .[test]test_serach1 with browser2 . Finished in 0.008025981 seconds. 2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 100% passed 249.19 tests/s, 0.00 assertions/s -- 私は、Rakefileよりもrun-test.rbという名前でテストを実行するス クリプトを用意することが多くて、テスト全体の初期化処理 ($VERBOSE = trueにしてテスト時にwarningを見つけやすくすると か)なんかをそこに入れたりします。たとえば、こんな感じです。 https://github.com/activeldap/activeldap/blob/master/test/run-test.rb