2

私の知る限り、TDD の典型的なワークフロー (W1) は次のとおりです。

  1. 関数のテストを開発します。
  2. テストを実行し、失敗するのを確認します。
  3. 関数を開発します。
  4. テストを再度実行し、テストが成功するのを確認します。
  5. 1を繰り返します。

しかし、Meck やその他のモック フレームワークでは、ワークフロー (W2) は次のようになります。

  1. すべての関数のテストを作成し、それらが失敗するのを観察します。
  2. モック オブジェクトを使用して、完全なシステム プロトタイプ (すべての機能とその相互作用) を開発します。
  3. テストを再度実行し、テストが成功するのを確認します。
  4. 各モック関数を段階的に実際の関数に徐々に変更します。

私は、W2 には W1 よりもいくつかの利点があると考える傾向があります。

  • 書くのが速い。
  • すべてのテスト (単体テストと統合テストの両方) が事前に作成されるため、統合が容易になります。また、彼らは最初から合格します。

したがって、質問は次のとおりです。

W2 には、上記の利点がありますか? いいえの場合、メックを確立されたルーチンとして日常の開発にどのように組み込むことができますか?つまり、メックを使用するワークフローは何ですか? それとも、ガイダンスなしでメックをランダムに使用する必要がありますか?

4

2 に答える 2

3

テストに合格するためにモックを排他的に使用することはできません。それが可能であれば、テストはその名前に値しないか、モックを「実際の」コードに置き換える必要はありません。モックはコードで実行したいことを既に実行しているためです。

モックは通常、テスト対象のシステム (SUT)、つまりテストしたいクラスをその依存関係から分離するために使用されます。依存関係はモックされますが、SUT はモックされません。

于 2012-08-23T06:15:33.430 に答える
1

W2 は、作業を開始する前にシステムの正しい設計を完了していることを前提としています。たとえば、私がそのような立場になることはめったにありません。事前に大きな設計を行う必要があります。IME は、開発プロセスの費用のかかる部分を排除するのではなく、移動したことを意味します。また、最初の設計に欠陥があった場合 (今後もそうなる可能性があります)、修復には費用がかかります。

最初から通過するテストはバグであり、機能ではありません。具体的に失敗したテストを書くことは重要なステップです。あなたが書いたコードが実際に機能することを他にどのように実証しますか?

メックと具体的に話すことはできませんが、モック オブジェクトのさまざまなフレーバーを自然に組み込んだ一般的な TDD ワークフローについて話すことができます。モック オブジェクトは、システムの残りの部分が機能するかどうかに関係なく単体テストを通過させるために存在します。また、次に何をする必要があるかについての自然な道しるべも提供します。単体テスト A に合格するためには、クラス B をモックする必要がありました。明らかに、次に行うことは、モックアップで説明されている方法で動作するクラス B を実装することです。

あなたの W1 は、いくつかの重要なステップを省略しています。それらを含めることで、モック オブジェクトが TDD で果たす役割が明確になる可能性があります。疑似 Perl として示すと、TDD は次のようになります。

while (not $project->is_feature_complete()) {
  my $feature_test = write_feature_test();
  die "You screwed up" if $feature_test->does_pass();
  $feature_test_suite->add($feature_test);
  while (not $feature_test_suite->does_pass()) {
    my $test = write_unit_test();
    die "You screwed up" if $test->does_pass();
    $unit_test_suite->add($test);
    while (not $unit_test_suite->does_pass()) {
      write_exactly_enough_code_to_pass_unit_test();
      while ($project->has_duplication()) {
        $project->eliminate_duplication();
      }
    }
  }
}

W1 との主な違いは次のとおりです。

  • 単体テストのサイクルの周りには、機能テストの別のサイクルがあります。
  • 機能テストはしばらく失敗し続ける可能性があります。すべての依存関係の統合が完了するまで、合格することはできません。
  • 私たちは単体テストに合格するために書くコードに非常に気を配っています。また、モック オブジェクトは実際のワーキング クラスよりも簡単に作成できるため、作成中に発見したすべての依存関係をモック アウトする必要があります。
  • 重複の排除は決定的に必要であり、モック オブジェクトを実際の実装に置き換えることがよくあるステップです。

最後の点については、さらに説明を加える必要があるかもしれません (できれば、例1によるテスト駆動開発全体を繰り返さないでください)。何が起こるかというと、2 番目のテストに合格するための最短の方法は、多くの場合、最初のテストに合格したモック オブジェクトのコピーを使用して、いくつかのパラメーターを調整することです。「重複の排除」ステップで、これら 2 つのモック オブジェクトを 1 つのパラメーター化されたオブジェクトに結合します。このサイクルを数回繰り返すと、作成したモック オブジェクトは必要な実際のオブジェクトとほとんど同じになるため、そのコードを使用して、これまで隠してきた依存関係の実装を開始できます。

これらすべてにおいて、モック オブジェクトの役割はほとんど常に同じです。つまり、システム全体を一度に実装しなくても、単体テストに合格できるようにすることです。それらを使用してシステム全体を事前に実装することは、それらのユーティリティのほとんどを無駄にしているように思えますが、大きな事前設計の通常のリスクにもさらされます。あなたが思っているほどの利益が得られるとは思いません。せいぜい、「コーディング」に費やされる時間が削減されるように会計を変更します。

于 2012-08-24T00:44:52.387 に答える