2011年2月 9日

[ruby-list:47850] ユニットテストでの sleep のスキップについて

畠山です。

自分でいろいろやってはみたもののうまい解決方法が見つからなかったので、もしどなたか何か良いアイデアがありましたらアドバイスお願いします。
(似たような状況は私以外にも多分結構あるだろうとも思うので少々長いですが投稿させてもらいます。)

* 問題状況
ユニットテストであるクラスのメソッドをテストしているのですが、いくつかのメソッドに sleep が入っています。
それぞれ数秒〜30秒くらいが設定されていて、これをそのままテストすると各テストで毎回数十秒間止まってしまいます。

(テスト数が多いのでこれはなんとか避けたい)
あるメソッドに関してはこの sleep はスキップしても問題ないのですが、あるメソッドでは sleep は必要な処理でテスト中でもスキップできません。

* やりたいこと(できたらうれしいこと)
そこであるテストケースだけ sleep をスキップして、あるテストケースでは sleep をスキップしない、ということはできるかどうか。

* やってみたこと
テストケースの始めに

def sleep(arg)
end

などと再定義すればスキップできますが、これではすべてのテストケースに反映されてしまいます。

また flexmock で

flexstub(Kernel).should_receive(:sleep)

などとしてもだめでした。
つまりは、flexmock を使って Kernel モジュールで定義されているメソッドを再定義できるとうれしいです。
もしくは、各テストケースで sleep を無理矢理 Thread#run させるようなことができてもうれしいです。
別々にテストをすれば済むことですが、テスト数が多すぎるので以下のような suite.rb を自前で用意して一括してテストを実行しています。

suite.rb
----
Dir.foreach(".") do |file|
if file =~ /test.+\.rb/ and file != __FILE__
require file
end
end


具体的には以下のテストで Klass1#method の sleep はスキップさせて、Klass2#method では sleep
を有効にできないか、と考えています。

klass.rb
----
class Klass1
def method
sleep(100)
end
end

class Klass2
def method
sleep(2)
end
end
----

testcase.rb
----
require 'klass'
require 'test/unit'

=begin
def sleep(arg)
arg
end
=end
class TestKlass1 < Test::Unit::TestCase
def test_method
obj = Klass1.new
assert_equal(100, obj.method)
end
end

class TestKlass2 < Test::Unit::TestCase
def test_method
obj = Klass2.new
assert_equal(2, obj.method)
end
end
----

長々すいませんでしたがどうぞよろしくお願いします。

畠山


投稿者 xml-rpc : 2011年2月 9日 03:25
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/101871
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。