Ruby+Minitest を使用してパラメータ化されたテストを作成する可能性はありますか?
概要
最近、Ruby+Minitest を使用する自動テスト プロジェクトに取り組み始めました。提供した入力データの数と同じ回数 1 つのテストを実行できるかどうか疑問に思っています。
だから、私は次のようなものを持っています(コードはNDAの下にあるため、実際の例を提供することはできません)
def test_new_registrations
result = process_new_entry(list_entries)
assert(validator_method(result), result)
end
重要なのは、process_new_entry メソッド内にループがあることです。このループを削除して、list_entries にあるエントリの数だけこのテストを実行するだけです。
Java+Selenium の TestNG から、テスト メソッド内で入力データを 1 つずつ渡すデータプロバイダーを使用するという概念を思い出しました。 同様のアプローチをここで実装できる可能性はありますか?
解決策
あなたが持っている場合:
class MyTest
TESTCASES = {
# input => expected
a: "a",
b: "b",
c: "c",
}
def test_testcases
TESTCASES.each do |entry, expected|
result = process_one(entry)
assert(expected, result)
end
end
end
そして、実際に各ケースを独自のテストで実行したい場合は、次のようにします。
MyTest
TESTCASES = {
# input => expected
a: "a",
b: "b",
c: "c",
}
TESTCASES.each do |entry, expected|
define_method("test_testcase_#{entry}") do
result = process_one(entry)
assert(expected, result)
end
end
end
Java とまったく同じ構文が本当に必要な場合は、上記をライブラリに変換して、これが機能するようにすることが可能です。
testcase_parameters(TESTCASES) # left as an exercise to the reader
def test_testcase(entry, expected)
assert(expected, process_one(entry))
end
しかし、それについてあまりにも間接的/抽象的であることに利点があるとは思えません。コードと実行状態を検査可能でデバッグしやすい状態に保ち、明示的に保つことをお勧めします。
class MyTest
TESTCASES = {
# input => expected
a: "a",
b: "b",
c: "c",
}
def test_testcases
results = TESTCASES.map do |entry, expected|
result = process_one(entry)
[entry, [expected, result]]
end
invalid_results = results.select { |e, (ex, res)| ex != res }
# This is a very easy-to-breakpoint place in code, to easily view all results:
# binding.pry
assert_empty invalid_results # failure cases will be printed out by test output
end
end