4

次の一連のイベントについて考えてみます。

  1. A()作業単位を実行する関数を作成します
  2. 関数A()のテストを記述して、バグが存在しないことを確認します
  3. B()関数を使った関数を書くA()
  4. 関数のテストB()を作成して、バグが存在しないことを確認します
    。4.1関数B()カバー関数A()のテスト結果として、同じ機能のいくつかをカバーする少なくとも2つのテストがあります。

質問1:最初に関数のテストを書くことは価値がありましたA()か?

  1. あなたはたくさんのコードを書きます
  2. プログラムの機能をエンドツーエンドでテストする巨大な回帰テストを作成します
    。6.1この単一の回帰テストは、すでに作成されたテストの大部分を効果的に繰り返します。

質問2:これらの手順に従うことにより、コードには同じことを複数回カバーする多くのテストが含まれます。これを回避するテクニックはありますか?

推定:

この質問の目的のために、Bが2つのことを行い、そのうちの1つが全体としてAであると仮定してください。

void performLifeChoice() { // B()
  if (timeIsRight) {
     askForPromotion();   // A()
  } else {
     goBackToSchool();
  }
}
4

3 に答える 3

4

私の一般的な答えは「はい」です。2つの理由から、A()の単体テストを作成する価値があります。

1)B()とは異なるコンテキストからA()を呼び出すことになる可能性があります。その場合、A()が機能していることを知り、テストの重複を回避できます。A()のテストを個別に行わなかった場合、同等のコードブランチに対して、実質的に同じテストを2回書き直すことになります。

2)関連して、A()を個別にテストしないと、カメが完全に倒れてしまう可能性があります。関数C()がそのブランチの1つでB()を呼び出し、D()がC()などを呼び出すと想像してください...より高いレベルの関数のみをテストするパスに従うと、最終的にはますます多くの前提条件のセットをカバーする必要がある統合テストを使用します。個々のユニットを可能な限り最小のコンテキストでテストし続けることで、原則としてその問題を回避できます。

私の答えの暗黙の結論は、A()がB()以外の場所から呼び出されることが決してない場合、A()をプライベートにする価値があり、その時点でテストが「オプション」になる可能性があるということです。一方、そのテストを維持することは、B()が失敗したときに、A()を壊したためであることを特定するのに役立つという点で、依然として役立つ可能性があります。ケント・ベックの言葉によれば、「テストが失敗した場合、何が間違っている可能性がありますか?答えが1に近いほど、テストは「単位y」になります。」-コードのどこで問題が発生したかを正確に特定するのに役立つ単体テストがあると便利です。

では、事前条件を追加して、A()のテストを実際に複製せずに、B()のテストをどのように行うことができますか?

ここで、モック/スタブまたは同様の手法が役立ちます。B()が何をしているのかを考えると、実際にはA()を実行していません。これは「コーディネーター」として機能し、さまざまなパスに条件をパイプします。私の意見では、適切なテストは「TimeIsRightの場合、B()はA()を呼び出す必要があります」です。A()によって提供される回答はB()とは関係ありません。これは、A()の責任です。ユニットテストカバー。

そのフレームで、B()のテストでアサートする必要があるのは、A()が返すものではなく、TimeIsRightのときにA()が呼び出されることです。コードの詳細に応じて、たとえばインターフェイスを介して、またはA()の代わりに挿入される関数を介して、B()内でA()を「置換可能」にすることを検討できます。

于 2012-08-10T23:27:21.220 に答える
3

メソッドは同じクラスにあるように見えるので、

  • プライベートの場合A()は、テストするだけB()です。A()のテストの一部としてテストされB()ます。

  • 公開されている場合A()は、テストするときにテストしないでくださいB()A()別のテストでの正しさを確認します。次に、別のテストで、そのB() 呼び出しが A()適切に行われることを確認します。あなたの例では、それは状況askForPromotion()で呼び出されたかどうかを確認することを意味します。timeIsRight

A()とB()が別々のクラスにある場合は、状況が少し異なることに注意してください。

ちなみに、TDDアプローチでは、イベントの順序は2. 1. 4. 3.;)である必要があります。

于 2012-08-11T01:29:08.743 に答える
1

この例では、いいえ、私の意見では、Aだけのテストを作成する価値はありません。ただし、ほとんどの場合、AとBは両方ともパラメーターを取り、Bは可能なパラメーター入力の全範囲を実行することはありません。 Aの場合ですが、Aの単体テストは(すべきです!)、その場合のAの単体テストは、Bのパラメーター入力が何であっても、Bが通過しないパラメーターをカバーするため、無駄ではありません。

于 2012-08-10T22:51:09.967 に答える