[ruby-list:49742] Re: test-unitで使用するテストケースを動的に生成したい

From: Kouhei Sutou <kou@...>
Date: 2014-01-26 05:17:25 UTC
List: ruby-list #49742
須藤です。

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),
  古川大輔 <mogya99@yahoo.co.jp> 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

In This Thread