8

私はTDDの方法論に頭を悩ませようとしていますが、鶏が先か卵が先かという問題に遭遇しました.

次のメソッド シグネチャを検討してください。

string RemoveTokenFromString (string delimited, string token)

名前が示すように、このメソッドはtokenfromのすべてのインスタンスを削除しdelimited、結果の文字列を返します。

後で、このメソッドにはバグがあることがわかりました (たとえば、間違ったビットが文字列から削除されているなど)。そこで、バグが発生するシナリオを記述したテスト ケースを作成し、テストが失敗することを確認します。

バグを修正するとき、メソッドがその仕事を適切に行うには、より多くの情報が必要であることがわかりました。この情報は、パラメーターとしてのみ送信できます (テスト対象のメソッドは静的クラスの一部です)。

私は何をしますか?バグを修正すると、単体テストを変更せざるを得なくなります-それは「正しい」TDD方法論でしょうか?

4

7 に答える 7

7

あなたはTDDで最も危険な罠に陥っています。TDDはテストに関するものだと思いますが、そうではありません。ただし、TDDのすべての用語はテストに関するものであるため、その罠にはまりやすいです。これがBDDが発明された理由です。BDDは本質的にTDDですが、紛らわしい用語はありません。

TDDでは、テストは実際にはテストではなく、例です。そして、アサーションは実際にはアサーションではなく、期待です。そして、あなたはユニットを扱っているのではなく、行動を扱っているのです。BDDはそれらを単にそれと呼んでいます。(注:BDDは最初に発明されてから進化し、現在はTDDの一部ではないものが組み込まれていますが、当初の意図は「多くの人がTDDを間違っているので、別の言葉を使って正しく行う」ことでした。 )。

とにかく、テストをテストとしてではなく、メソッドがどのように機能するかを示す動作例と考えると、予想される動作をよりよく理解するにつれて、テストの削除または変更が許可されるのはTDD、それが唯一の正しい選択です!常にそれを覚えておいてください!

于 2009-04-08T17:41:28.047 に答える
6

ユニットの意図された動作が変更されたことを発見したときに、テストを爆撃することはまったく問題ありません。

//Up front
[Test]
public void should_remove_correct_token_from_string()
{
  var text = "do.it.correctly..";
  var expected = "doitcorrectly";
  Assert.AreEqual(StaticClass.RemoveTokenFromString(text, "."), expected);
}

//After finding that it doesn't do the right thing
//Delete the old test and *design* a new function that
//Does what you want through a new test
//Remember TDD is about design, not testing!
[Test]
public void should_remove_correct_token_from_string()
{
  var text = "do.it.correctly..";
  var expected = "doitcorrectly";
  Assert.AreEqual(
      StaticClass.RemoveTokenFromString(
          text,
          ".",
          System.Text.Encoding.UTF8), expected);
}

//This will force you to add a new parameter to your function
//Obviously now, there are edge cases to deal with your new parameter etc.
//So more test are required to further design your new function
于 2009-04-08T06:39:20.993 に答える
4

複雑にしないでおく。

単体テストが間違っていたり、時代遅れになっている場合は、書き直さなければなりません。仕様が変更された場合、または特定の仕様が関連しなくなった場合、単体テストはそれを反映する必要があります。

赤、緑、リファクタリングは、テストしているコードだけでなく、単体テストにも適用されます。

于 2009-04-08T06:45:49.637 に答える
2

ここで役立つAdd Parameterというリファクタリングがあります。

お使いの言語がメソッドのオーバーロードをサポートしている場合は、最初に新しいパラメーターを使用して新しい関数を作成し、既存の関数の本体をコピーして問題を修正できます。

問題が修正されたら、すべてのテストを 1 つずつ変更して、新しいメソッドを呼び出すことができます。最後に、古いメソッドを削除できます。

メソッドのオーバーロードをサポートしていない言語では、別の名前で新しい関数を作成し、その新しい関数の既存の関数の本体をコピーし、既存の関数で新しい関数を呼び出します。新しいパラメーターのダミー値を使用する可能性があります。その後、すべてのテストに合格することができます。古いテストで新しい関数を 1 つずつ呼び出すようにします。古いメソッドが使用されなくなったら、削除して新しい関数の名前を変更できます。

これは少しプロセスが大きくなりますが、これがレッド グリーン リファクタリングに従う TDD の方法だと思います。

利用可能な場合、パラメータのデフォルト値も役立ちます。

于 2009-04-08T06:41:24.750 に答える
1

「正しい」/「正しい」方法について心配しないでください...ソリューションにすばやく近づくのに役立つものは何でも。

追加のパラメータを取り込む必要がある場合は、

  • テストケースの通話を更新する
  • 新しいパラメータを実際のメソッドに追加します
  • コードがビルドされ、テストが再度失敗することを確認します。
  • 緑にすることを続行します。

新しいパラメーターを追加するとコンパイルエラーが無数に発生する場合にのみ、お勧めします-赤ちゃんのステップでそれを取る...本当に3番目のパラメーターが必要ないことを知る前にソースベース全体を更新したくない、またはあなたは4番目のものが必要です..時間が失われました。したがって、すべての参照を更新する前に、メソッド「working」の新しいバージョンを入手してください。(フィリップがここで言うように)

  • 追加されたパラメーターを使用して新しいオーバーロードを書き込みます
  • 古いメソッドのコードを新しいオーバーロードに移動します
  • 古いオーバーロードリレーを作成するか、新しいパラメータのデフォルト値を使用して新しいオーバーロードに委任します
  • これで、手元のタスクに戻り、新しいテストをグリーンにすることができます。
  • 古いオーバーロードが不要になった場合は、それを削除して、結果として生じるコンパイルエラーを修正してください。
于 2009-04-08T07:59:52.080 に答える
1

赤、緑、リファクタリング。

何をするにしても、最初に、バグを再現するテスト ケースをコンパイルするが失敗する状態にする必要があります。その後、パラメーターのみをテストと実装に追加することができますが、それには何もしないので、まだ赤のままです。

于 2009-04-08T06:29:54.340 に答える
0

メソッドがジョブを正しく実行していない場合は修正する必要があり、修正に署名の変更が必要な場合は、その点で間違っていることに注意してください。TDDに従って、最初にテストケースを作成しますが、これは確実に失敗します。次に、テストを満たすメソッドを作成します。このアプローチに従って、テストでのメソッド呼び出しが機能するためにパラメーターが必要な場合は、それを実行する必要があります。

于 2009-04-08T06:37:57.427 に答える