3

MiniTest で Ruby 1.9.3 を使用しています。テストごとに 1 つのアサーションを使用することがベスト プラクティスであることはわかっていますが、配列を比較する場合など、動的にアサーションを作成したい場合があります。

if added_skus.each { |s| assert(skus_in_cart.include?(s), "SKUs #{added_skus} or SKU amount do not match SKUs #{skus_in_cart} on Cart page.") }
  puts "Product SKUs #{added_skus} match SKUs #{skus_in_cart} on Cart page."
end

ご存知のように、最初のアサーションの失敗に達すると、テストは終了します。テストを続行し、テスト終了後にすべての失敗を報告したいと思います。

古いバージョンの test/unit と Ruby 1.8.7 (test/unit ライブラリの add_failure メソッド) を使用したソリューションを見つけましたが、MiniTest と Ruby 1.9.3 の適切なソリューションが見つかりません。フィードバックをいただければ幸いです (それが間違っていることを意味する場合でも、正しい方向に向けてください)。ありがとう!

4

1 に答える 1

2

解決策1-アサーションを1つのアサーションに結合します。

すべてのSKUを一緒に検討することで、現在のコードを単一のアサーションとして記述できます。

#Determine the missing skus:
missing_skus = added_skus.find_all{ |s| not(skus_in_cart.include?(s)) }

#Assert that there are no missing skus:
assert( missing_skus.empty?, "SKUs #{missing_skus} do not match SKUs on Cart page." )

解決策2-複数の要素をアサートするためのカスタムメソッド:

アサーションカウントを(セット全体ではなく)個々のSKUごとに設定したい場合は、カスタムアサーションメソッドを作成できます。これがソリューション1に比べて実際のメリットをもたらすとは思いませんが。

実行中のコードの例:

'テスト/ユニット'が必要

module MiniTest::Assertions
    #Asserts that each element passes the test
    # Inputs:
    #   enumerable - The object to iterate over (ex an array)
    #   msg - Custom message to include in assertion failure
    #   test - A block that each element will be tested against
    def assert_each(enumerable, msg = nil, &test)
        msg ||= "No message given."

        failed_elements = Array.new
        enumerable.each do |e|
            self._assertions += 1
            failed_elements << e unless yield(e)
        end

        msg = " #{failed_elements} failed assertion. #{msg}"    
        raise( MiniTest::Assertion, msg ) unless failed_elements.empty?
    end
end

class MyTest < Test::Unit::TestCase
    def test()
        added_skus = ['b', 'a', 'c', 'd']
        skus_in_cart = ['c', 'b']

        assert_each(added_skus, "SKUs missing from cart."){ |s| skus_in_cart.include?(s) }
    end
end
于 2013-01-28T03:41:33.137 に答える