私は、関数がリストで期待されていることを実行することをテストしています。テストしたい
f(null) -> null
f(empty) -> empty
f(list with one element) -> list with one element
f(list with 2+ elements) -> list with the same number of elements, doing what expected
そうするために、最善のアプローチは何ですか?
一連のテストを1つのテストケースで実行するか、多数のテストケースで実行するかについて、私が使用する単純な経験則は次のとおりです。
したがって、複数の要素についてそれをテストしていた場合、すべての要素が処理され、正しい結果が導き出された場合、2つ以上のアサートがある可能性がありますが、リストを一度設定するだけで済みます。したがって、1つのテストケースで問題ありません。
あなたの場合でも、私はnullリスト、空のリストなどを設定する必要があります。それは複数の設定です。したがって、この場合は必ず複数のテストを作成します。
他の人が述べたように、これらの「複数のテスト」は、単一のパラメーター化されたテストケースとして存在できる可能性があります。つまり、同じテストケースがさまざまなセットアップデータに対して実行されます。これが実行可能な解決策であるかどうかを知るための鍵は、テストの他の部分、「アクション」と「アサート」にあります。各データセットで同じアクションとアサートを実行できる場合は、このアプローチを使用してください。たとえば、データのさまざまな部分に対してさまざまなコードを実行するためにif
を追加する場合、これは解決策ではありません。後者の場合は、個別のテストケースを使用します。
トレードオフがあります。 1つのテストでパックする数が多いほど、タマネギの効果が合格する可能性が高くなります。言い換えれば、最初の失敗はそのテストを停止させます。最初の失敗を修正するまで、他のアサーションについてはわかりません。とは言っても、セットアップコードを除いてほとんど同じような単体テストがたくさんあるのは、書かれている作業とそうでない作業があることを見つけるためだけに多くの忙しい作業です。
フレームワークに基づいて可能なツール:
Assume.that()
は、前提条件が満たされない場合、データのテストを単にスキップします。これにより、「期待どおりに機能する」を定義して、単純に大量のデータを供給することができます。結果を表示すると、親テストのエントリがあり、次に各データのサブエントリがあります。私のテストではassert
ステートメントは1つしか存在できないという厳密な考え方はありませんが、すべてのアサートが単一のアクションの事後条件をテストするという制限を設けています。テスト間の唯一の違いがデータである場合、私はパラメーター化されたテストや理論などのより高度なデータ駆動型テスト機能を使用するという考え方があります。
最良の結果が何であるかを決定するためにオプションを比較検討してください。 「WorksAsExpectedWhenNull」は、要素の数が異なるコレクションを処理する場合とは根本的に異なると言います。
これらは異なるテストケースですが、テストのコードは同じです。したがって、パラメーター化されたテストを使用することが最善のソリューションです。テストフレームワークがパラメーター化をサポートしていない場合は、共有コードをヘルパー関数に抽出し、個々のテストケースから呼び出します。
1つのテストケース内のループによるパラメーター化は避けてください。エラーの原因となったデータセットを特定するのが困難になるためです。
TDDの赤、緑、リファクタリングサイクルでは、一度に1つのサンプルデータセットを追加する必要があります。複数のテストケースを組み合わせてパラメーター化されたテストを行うことは、リファクタリング手順の一部になります。
かなり異なるアプローチは プロパティテスト です。具体的な入力データを指定せずに、関数のさまざまなプロパティを表明するさまざまな(パラメーター化された)テストを作成します。例えば。プロパティは次のようになります。すべてのリストxs
の場合、リストys = f(xs)
はxs
と同じ長さです。次に、テストフレームワークは、興味深いリストとランダムリストを生成し、プロパティがそれらすべてに対して保持されることをアサートします。手動で例を選択すると、興味深いEdgeケースを見逃す可能性があるため、これは手動での例の指定から離れます。
各ケースで1つのテストを行うことは適切です。各テストで単一の概念をテストすることは、多くの場合推奨される良いガイドラインであるためです。
この投稿を参照してください: 1つの単体テストで複数のアサートを設定しても問題ありませんか? 。関連する詳細な議論もあります:
私のガイドラインは通常、テストごとに1つの論理CONCEPTをテストすることです。同じオブジェクトに複数のアサートを設定できます。彼らは通常、テストされている同じ概念になります。 出典-Roy Osherove
[...]
テストは1つの理由でのみ失敗するはずですが、Assertステートメントが1つだけであることを常に意味するわけではありません。私見では、「アレンジ、アクト、アサート」のパターンを守ることがより重要です。
重要なのは、アクションが1つだけあり、アサートを使用してそのアクションの結果を検査することです。しかし、それは「アレンジ、アクト、アサート、テストの終了」です。別のアクションを実行してテストを続行し、その後さらにアサートしたい場合は、代わりに別のテストを作成してください。 ソース
私の考えでは、それはテスト条件に依存します。