5

次のクラス(〜pseudocode)をテストしていると仮定しましょう。

// (...)
public Result Process(Image image)
{
    Image image2 = PreprocessImage(image);
    PartialResult r1 = Process1(image2);
    PartialResult r2 = Process2(r1);
    Result result = FinalProcessing(r2);

    return result;
}

public Image PreprocessImage(Image image)
{
    Image tmp1 = Resize(image);
    Image tmp2 = Blur(tmp1);
    Image tmp3 = Median(tmp2);
    Image tmp4 = ExtractSpecificAreas(tmp3);

    return tmp4;
}

public Image Median(Image image)
{
     // Actual image median algorithm
}

問題をさらに...問題にするために、これらのメソッドのほとんど(たとえば、Process1、Process2、FinalProcessing、ExtractSpecificAreas)の結果は、たとえば、ほとんど予測できないと仮定しましょう。たとえば、ヒューリスティック/決定的なアルゴリズムがいくつかあります。画像から特徴を抽出します。90%の状況で成功する可能性があり、それは許容範囲です。

これらの方法のどれを単体テストしますか?無効な入力/境界条件を除いて、これらのメソッドをどのように単体テストしますか?単体テストが意味をなすための方法は、どの程度基本的であるか(またはどれほど複雑である可能性がありますか)?

4

2 に答える 2

9

単体テストの一般的なルールは、テストできる最小のピースをテストすることです。良いルールは、各テストがパブリックAPIから正確に1つのメソッドを実行する必要があるということです。

つまり、このメソッドのみを実行する必要があり、一時的であっても他のメソッドは実行しないでください。したがって、テストしたいときにfoo()それが呼び出された場合は、それもテストするのではなく、bar()モックする必要があります。bar()ただし、内部のプライベートメソッドを呼び出すbaz()ことは問題ありません。

メソッドが何百もの内部メソッドを呼び出す場合、リファクタリングが必要になります。

理由は、単体テストで失敗すると、問題の正確な場所を示す必要があるということです。単体テストを行う場合main()、失敗すると、プロジェクトのコードのどこかにバグがあることがわかります。たとえば、String.length()を単体テストし、そのテストが失敗した場合、バグがどこにあるべきかを正確に把握できます。

これはあなたの質問にも答えます:あなたには予測できない結果を返すメソッドがあります。それらをモックすると、常に既知の良い/悪い結果を返すことができるので、それらの結果を適切に処理するメソッドをテストできます。

予測できない方法については、同様の戦略を見つける必要があります。ここでは、たとえば、トレーニングされたニューラルネットワークがどこかにあると想定しています。したがって、テストでは、画像が90%の確率で正しくソートされていると確信できるまで、いくつかのトレーニング画像をメソッドにN回渡すことができます。

ここでも、これらのメソッドを予測可能な部分と予測不可能な部分に分割して、モックまたは統計分析でテストできるようにする必要があります。

2つの優れたモックフレームワークは、MockitoPowerMockです。

于 2013-03-05T08:33:53.023 に答える
1

Aaron Digulla はすでに最も重要なことを指摘していると思います: 可能な限り最小の部分をテストし、モック オブジェクトを使用します。

しかし、もう 1 つ付け加えさせてください。アプリケーション全体をテストすることもできます。つまり、小さな部分がうまく連携しているかどうかをテストすることもできます (これは単体テストではなく統合テストになりますが、とにかく両方を行う必要があります)。ヒューリスティック アルゴリズムをテストするには、解決するのが簡単なタスクから始めると便利であることがわかりました。あなたの場合、それは「簡単な」イメージのようなものです。もちろん、これはベースラインを提供するだけであり、90% の状況で機能することを保証するものではありません。とにかく、開発中には役に立ちます。必要に応じて、より現実的なサンプルで (統合) テスト スイートをいつでも強化できます。

于 2013-03-05T08:48:14.060 に答える