15

私はTDDをテーマにした本やウェブサイトをたくさん読んだことがありますが、それらはすべて、特にケントベックの本で非常に理にかなっています。しかし、自分でTDDをやろうとすると、どうやって始めたらいいのかとキーボードを見つめています。使用しているプロセスはありますか?あなたの思考プロセスは何ですか?最初のテストをどのように特定しますか?

この主題に関する本の大部分は、TDDとは何かを説明するのに優れた仕事をしていますが、実際の重要なアプリケーションでTDDを実践する方法については説明していません。TDDはどのように行いますか?

4

8 に答える 8

5

実際、思ったより簡単です。個々のクラスでTDDを使用するだけです。クラスにあるすべてのパブリックメソッドは、考えられるすべての結果についてテストする必要があります。したがって、表示される「概念実証」TDDの例は、数百のクラスを持つ比較的大規模なアプリケーションでも使用できます。

使用できるもう1つのTDD戦略は、メインのアプリの動作をカプセル化することにより、アプリケーションのテスト実行自体をシミュレートすることです。たとえば、アプリケーションを表すフレームワーク(C ++で作成しましたが、これはすべてのオブジェクト指向言語に適用されるはずです)を作成しました。初期化、メイン実行ループ、およびシャットダウンのための抽象クラスがあります。したがって、私のmain()メソッドは次のようになります。

int main(int argc, char *argv[]) {
  int result = 0;

  myApp &mw = getApp(); // Singleton method to return main app instance
  if(mw.initialize(argc, argv) == kErrorNone) {
    result = mw.run();
  }

  mw.shutdown();
  return(result);
}

これを行う利点は2つあります。まず、すべての主要なアプリケーション機能を静的ライブラリにコンパイルできます。静的ライブラリは、テストスイートとこのmain.cppスタブファイルの両方に対してリンクされます。次に、argcとargv []の配列を作成し、main()で何が起こるかをシミュレートすることで、メインアプリケーションの「実行」全体をシミュレートできることを意味します。このプロセスを使用して多くの実世界の機能をテストし、入力データとコマンドライン引数の特定の実世界のコーパスが与えられた場合に、アプリケーションが想定どおりに動作することを確認します。

さて、あなたはおそらく、実際のGUIやWebベースのインターフェースなどを備えたアプリケーションでこれがどのように変わるのか疑問に思っているでしょう。それに対して、私は単にモックアップを使用してプログラムのこれらの側面をテストすると言います。

しかし、要するに、私のアドバイスはこれに要約されます。テストケースを最小レベルに分解してから、上向きに見始めます。最終的に、テストスイートはそれらをすべてまとめてスローし、最終的には妥当なレベルの自動テストカバレッジになります。

于 2008-10-17T08:06:45.813 に答える
4

私も同じ問題を抱えていました。以前は、ウィンドウデザイナーを起動して、実装したい最初の機能のUIを作成することで、ほとんどの開発を開始していました。UIは、この作業方法をテストするのが最も難しいものの1つであるため、TDDにうまく変換されません。

PresenterFirstのアトミックオブジェクトペーパーは非常に役に立ちました。私はまだ、実装したいユーザーアクションを想定することから始め(開始するのに最適なユースケースがある場合)、MVPまたはMVC風のモデルを使用して、最初の画面のプレゼンターのテストを作成することから始めます。プレゼンターが機能するまでビューをモックアップすることで、この方法で非常に速く始めることができます。http://www.atomicobject.com/pages/Presenter+まず、この方法での作業の詳細については、こちらをご覧ください。

未知の言語またはフレームワークでプロジェクトを開始している場合、または未知の数が多い場合は、最初にスパイクを実行することから始めることができます。私はスパイクの単体テストも作成することがよくありますが、スパイクしているコードを実行するためだけです。スパイクを実行すると、実際のプロジェクトを開始する方法についての情報が得られます。実際のプロジェクトを開始するときは、スパイクを捨てることを忘れないでください

于 2008-10-17T08:06:37.187 に答える
3

私は要件の思考から始めます。

foreachユースケース

  1. ユースケースを分析する
  2. 将来のクラスを考える
  3. テストケースを書き留める
  4. テストを書く
  5. クラスのテストと実装(ポイント4でsthを逃した場合は、新しいテストを追加することがあります)。

それでおしまい。とてもシンプルですが、時間がかかると思います。私はそれが好きです、そして私はそれに固執します。:)

もっと時間があれば、EnterpriseArchitectでいくつかのシーケンシャルダイアグラムをモデル化しようとしています。

于 2008-10-17T08:00:51.613 に答える
1

プロセスをブートストラップするのが特に難しいことに同意します。

私は通常、最初の一連のテストを映画の脚本のように考えようとしますが、おそらく映画の最初のシーンだけを考えます。

Actor1 は Actor2 に世界が困っていることを伝え、Actor2 はパッケージを返し、Actor1 はパッケージを解凍します。

これは明らかに奇妙な例ですが、相互作用を視覚化することは、最初のこぶを乗り越える良い方法であることがよくあります。大規模なグループでうまく機能する類似のテクニック (ユーザー ストーリー、RRC カードなど) は他にもありますが、それはあなたが一人でいるように思え、余分なオーバーヘッドは必要ないかもしれません。

また、あなたが別の本を読むのは絶対に避けたいことだと思いますが、MockObjects.com の担当者は、現在、Growing Object-Oriented Software, Guided by Testsというタイトルの初期ドラフト段階の本を持っています。現在レビュー中の章では、TDD を開始して全体を通して継続する方法について、さらに詳しい洞察が得られるかもしれません。

于 2008-10-17T08:13:48.077 に答える
1

問題は、どのテストを作成する必要があるのか​​疑問に思ってキーボードを見ていることです。

代わりに、書きたいコードを考え、そのコードの最初の小さな部分を見つけて、その小さなコードを書くように強制するテストを考えてみてください。

最初は、非常に小さなピースで作業するのに役立ちます。1 日のうちでも、より大きなチャンクで作業することになります。しかし、行き詰まったときはいつでも、次に書きたい最小のコード片を考えて、それに対するテストを書いてください。

于 2008-11-17T00:35:06.287 に答える
0

私はあなたが本当にTDDから始めるべきではないと思います。真剣に、あなたのスペックはどこにありますか?システムの一般的/大まかな全体的な設計についてはまだ合意していますか?それはアプリケーションに適している可能性がありますか?TDDとアジャイルがBigDesignUp-Frontを思いとどまらせることは知っていますが、それは、その設計の実装をTDDする前に、最初にDesignUp-Frontを実行するべきではないという意味ではありません。

于 2008-10-17T08:03:24.027 に答える
0

コードが「テストに適していない」(簡単にテストできる) ため、TDD の実行方法がわからない場合があります。

いくつかの優れたプラクティスのおかげで、クラスを分離してテストしやすくなり、真の単体テストを実現できます。

最近、Google の従業員によるブログに出くわしました。このブログでは、クラスとメソッドを設計してテストしやすくする方法について説明しています。

これは、私がお勧めする彼の最近の講演の 1 つです

彼は、依存性注入パターンを使用して、ビジネス ロジックをオブジェクト作成コードから分離する必要がある (つまり、ロジックと「new」演算子を混在させないようにする) 必要があると主張しています。また、デメテルの法則がテスト可能なコードにとっていかに重要であるかについても説明しています。彼は主に Java コード (およびGuice ) に焦点を当てていますが、彼の原則は実際にはどの言語にも当てはまるはずです。

于 2008-11-17T01:33:03.270 に答える
0

最も簡単な方法は、依存関係のないクラス、つまり他のクラスで使用されているが別のクラスを使用していないクラスから始めることです。次に、「このクラス (このメソッド) が正しく実装されているかどうかをどうやって知ることができるでしょうか?」と自問して、テストを行う必要があります。

次に、オブジェクトが初期化されていないときにオブジェクトに問い合わせる最初のテストを作成し、NULL を返すか、例外をスローすることができます。次に、オブジェクトを初期化 (おそらく部分的にのみ) し、テスト テストを実行すると、価値のあるものが返されます。次に、別の初期化値でテストを追加できます-同じように動作するはずです。そのとき、私は通常、無効な値でオブジェクトを初期化しようとするなど、エラー状態をテストします。

メソッドの処理が完了すると、クラス全体の処理が完了するまで、同じクラスの別のメソッドに移動します。

次に、別のクラス (別の独立したクラス、または実装した最初のクラスを使用するクラス) を選択できます。

最初のクラスに依存するクラスを使用する場合、テスト環境 (または 2 番目のクラス) が完全にテストされているため、最初のクラスをインスタンス化しても問題ないと思います。クラスに関する 1 つのテストが失敗した場合、どのクラスに問題があるかを判断できるはずです。

最初のクラスで問題を発見したり、特定の条件下で正しく動作するかどうかを尋ねたりした場合は、新しいテストを作成してください。

記述しているテストが単体テストとして認定される多くのクラスにまたがっていると思われる依存関係を登る場合は、モック オブジェクトを使用して、システムの残りの部分からクラスを分離できます。


Jon LimJap からの回答のコメントで示したように、既にデザインを持っている場合、TDD は単体テストを使用してデザインを出現させることであるため、純粋な TDD を行っているわけではありません。

そうは言っても、すべてのショップが厳密なTDDを許可しているわけではなく、手元に設計があるので、それを使用してTDDを実行しましょう-テストファーストプログラミングと言ったほうがよいかもしれませんが、それはポイントではありません。 TDD始めました。

于 2008-11-17T07:33:58.830 に答える