3

次のようなテストクラスを書くと

class MyTest < Test::Unit::TestCase 
  def setup 
  end

  def test_1 
    flunk
  end

  def test_1 
    assert true
  end
end

最初の test_1 は無視されます。ばかげた間違いのように見えますが、コピー アンド ペースト プログラミングで発生する可能性があります。ランニング以外にも

grep test test_me.rb | wc

それを、テストユニットが実行したと言うテストの数、rcov や heckle を使用する、または -w を使用して実行するテストと比較すると、どのようにしてそのような問題を検出できますか?

また、テストメソッドを上書きしないように指定する方法はありますか?

編集: テストされているメソッドには、6 つほどの可能な値を持つパラメーターがあり、テスターは各シナリオをテストしたいと考えていました。これが、コピー アンド ペースト プログラミングが使用された理由です。このようなシナリオで想定できる唯一の代替案は、パラメーターと期待値の 6 要素配列です。

4

6 に答える 6

5

method_addedメソッドがクラスに追加されるたびに呼び出されるRubyを利用できます。含めるモジュールに何かを入れることができるはずですが、これはテストクラス内でそれを行う簡単な例です。

class MyTest < Test::Unit::TestCase

  @@my_tests = []

  def self.method_added(sym)
    raise "#{sym} already defined!" if @@my_tests.include? sym
    @my_tests << sym
  end

  def test_foo_1
  end

  def test_foo_2
  end

  def test_foo_1
  end
end
于 2009-02-20T17:44:07.067 に答える
2

編集:テストされているメソッドには、6程度の可能な値を持つパラメーターがあり、テスターは各シナリオをテストしたいと考えていました。これが、コピーアンドペーストプログラミングが使用された理由です。

そのような状況では、私はこれを行います:

def test_foo
  test_cases = [
   {:param => 1, :expected => 'whatever is expected'},
   {:param => 2, :expected => 'whatever is expected'},
   {:param => 3, :expected => 'whatever is expected'},
   {:param => 4, :expected => 'whatever is expected'},
   {:param => 5, :expected => 'whatever is expected'},
   {:param => 6, :expected => 'whatever is expected'}
  ]

  for test_case in test_cases
    do_the_test(test_case)
  end
end

def do_the_test(test_case)
  # test code here
end

これは、言われているように、コピーアンドペーストを完全に回避します。

このようなシナリオで想定できる唯一の選択肢は、パラメーターと期待値の6要素配列です。

その通り!

于 2009-02-21T10:00:58.840 に答える
2

HermanD の回答に関しては、これは Ruby であるため、クラスで直接これを実行して、独自のテスト メソッドを作成することもできます。

class MyObjectTest < Test::Unit::TestCase
  [
   {:param => 1, :expected => 'whatever is expected'},
   {:param => 2, :expected => 'whatever is expected'},
   {:param => 3, :expected => 'whatever is expected'},
   {:param => 4, :expected => 'whatever is expected'},
   {:param => 5, :expected => 'whatever is expected'},
   {:param => 6, :expected => 'whatever is expected'}
  ].each do |test_case|
    define_method :"test_using_#{test_case[:param]}_should_return_#{params[:expected].underscore}" do
      assert_equal test_case[:expected], MyObject.new.do_something_with(test_case[:param])
    end
  end
end

Rspec (または Shoulda) の文のような言語を使用すると、さらに自然に感じられます。

describe MyObject do
   [
   {:param => 1, :expected => 'whatever is expected'},
   {:param => 2, :expected => 'whatever is expected'},
   {:param => 3, :expected => 'whatever is expected'},
   {:param => 4, :expected => 'whatever is expected'},
   {:param => 5, :expected => 'whatever is expected'},
   {:param => 6, :expected => 'whatever is expected'}
  ].each do |test_case|
    it "should return #{test_case[:expected]} when using #{test_case[:param]}" do
      MyObject.new.do_something_with(test_case[:param]).should == test_case[:expected]
    end
  end
end
于 2009-02-21T12:32:20.740 に答える
1

テストに適切な説明的な名前を付けている場合、これは本当に問題ですか? 以下は、私の最近のプロジェクトのテスト メソッド名の例です。

test_should_not_do_html_escaping_for_administrators
test_should_not_be_able_to_create_project_with_company_user_doesnt_own
test_should_be_able_to_edit_own_projects
test_should_not_be_able_to_edit_others_projects

テスト名が簡単に上書きしたり複製したりできるほど短い場合は、それぞれのテストで実際に何をテストしているのかを十分に説明していない可能性があります。

于 2009-02-19T23:16:09.303 に答える
0

test-unit の gem バージョンには、2.0.7 以降のテストの再定義を検出する機能があります。

于 2010-03-09T22:49:48.300 に答える
0

コピー アンド ペースト プログラミングは避けてください。必要に応じてキー ショートカットを再バインドします。

于 2009-02-20T12:16:54.590 に答える