2009-06-01 8 views
14

私はユニットテストをいくつか行い、テストを書く経験がありますが、TDDを設計ツールとして完全に受け入れていません。TDD:最初のテストを開始する場所

私の現在のプロジェクトは、企業の組立プロセスの一部としてシリアル番号を生成する既存のシステムを再作業することです。私は、既存のシステムを見て、現在のプロセスとワークフローを理解しています。また、新しい要件のリストと、それらがどのようにワークフローを変更するのかについてのリストもあります。

私はプログラムを書く準備ができているように感じ、私は最後からTDDを最初から最後まで強制することにしました。

しかし、今どこから始めたらいいのか分かりません。 (私はTDDプロセスを欺いているのだろうか?ユーザーのプログラムフローのアイデアは既に持っているのだろうか?)

ユーザフローは本当にシリアルであり、一連のステップに過ぎない。一例として、最初のステップは次のようになります。

  • ユーザは、製造指図番号を送信し、次のステップは、ユーザが開始される材料

の注文紙幣のシリアライズ可能な部品番号のリストを受信します部品番号の1つを選択します。

私はこの最初のステップを出発点として使用できると考えていました。製造指図番号を取り、部品番号のリストを返すコードがほしいと思います。

// This isn't what I'd want my code to end up looking like 
// but it is the simplest statement of what I want 
IList<string> partNumbers = GetPartNumbersForMfgOrder(string mfgOrder); 

ケントベックスの例題の本を読んで、小さなテストを選ぶことについて話します。これは非常に大きなブラックボックスのようです。それはmfgオーダーリポジトリを必要とするため、このmfgオーダーのすべての該当するパーツ番号を見つけるためにプロダクト構造ツリーをクロールしなければならず、コード内にドメインモデルも定義していません。

これは非常に一般的な高水準な機能であり、これは奇妙なスタートのようです。一方、私が低いレベルから始めれば、私は本当に自分が必要と思っているものを推測しているようで、それは反TDDのようです。


これは物語をどのように使うのですか?

私は正直であるために

をシリアル化するかを選ぶことができるようにするためMFG順 上の部品番号のリストを取得したいアセンブラ として、アセンブラはそれを言うことはありません。すべてのアセンブラは望んでいるmfgの順に操作を完了することです:

私はあなたが持っていると思う私はmfgの順

答えて

15

ここから始めます。このアプリケーションのコードが全くないとします。

  1. ユーザーストーリーとビジネス価値を定義します。「ユーザーとして、製造指図番号とその注文の部品番号のリストを提出して在庫システムに送信できるようにします"
  2. はUIで始まります。ラベル、リスト、ボタンの3つのフィールドを持つ非常に単純なページを作成します(Webアプリケーションを想定します)。それで十分ですね。ユーザーはリストをコピーしてinvシステムに送信することができます。
  3. パターンを使用して、MVCのようにデザインを行います。
  4. UIから呼び出されるコントローラメソッドのテストを定義します。 Assert.AreSame(3, controller.RetrieveParts(mfgOrder).Count)
  5. コントローラの単純な実装を記述して、何かが返されることを確認してください:return new List<MfgOrder>{new MfgOrder(), new MfgOrder(), new MfgOrder()};また、MfgOrderのクラスも実装する必要があります。
  6. あなたのUIは機能しています!間違って働いているが、働いている。したがって、コントローラがサービスまたはDAOからデータを取得することを期待してください。テストケースにMock DAOオブジェクトを作成し、メソッド "partsDao.GetPartsInMfgOrder()"が呼び出されるという期待を追加します。
  7. メソッドを使用してDAOクラスを作成します。コントローラからメソッドを呼び出します。あなたのコントローラーが完成しました。
  8. 別のテストを作成してDAOをテストし、最終的にDBから適切なデータが返されることを確認します。
  9. すべて完了するまで繰り返します。しばらくすると、あなたはそれに慣れます。

ここで重要な点は、アプリケーションを非常に小さな部分で分割し、それらの小さな部分を個別にテストすることです。

1

上で操作を終えることができるようにするためのシリアル番号 で部品をマークしたいアセンブラ として良いスタートだが、それほどそれを見ない。より多くのテストを発することになっているテストでは、それについて考えるか、製造指図番号や部品番号がまだわかっていますか?あなたは他のテストにつながる可能性のあるものを構築しなければなりませんが、最終的には私が信じている徹底的なテストに落ちます。ここで

は、ブレークダウンのビットを必要とする可能性の話です:私は、製造オーダー番号を提出し、材料 の受注法案のシリアライズ可能な部品番号のリストを受信したいユーザーとして

  • 私は、物事を何度も繰り返し細かく分割して全体を構築することが重要だと思います。その "分割と征服"テクニックは時々便利です。 ;私はそれ以来、初めて:)

    をTDDをしようとしたとき)

+0

あなたはストーリーの第3の部分を忘れてしまいました。ビジネス上の利点(シリアライズ可能)をもたらさない実装の詳細もそこにあります。 私は、より良い物語は、 "私が在庫システムにリストを送ることができるように、製造注文番号とその注文の部品番号のリストを提出したいと思うユーザのようなものです"と言うでしょう。 –

+0

この文脈ではSerializableは実装ではありません。これは、どのパートにシリアル番号が付いているかを示すドメイン用語ですので、(要件を理解する限り)重要です。 –

+0

これが当てはまる場合は、あなたが正しいです。ドメイン専門知識はすべてです。 –

1

さてさて、あなたは私がやったとまったく同じ壁にぶつかるましたが、私はそれがリファクタリングがあまりにも高価なものにするという理由だけで、それをあきらめました - 私は開発の初期段階で多くのリファクタリングをする傾向があります。

途方もない言葉を使って、TDDの最も重要かつ最も重要な側面の1つは、実際に実装する前にクラスインターフェイスを定義することです。これは、すべての部品を1つの大きな製品に組み立てる必要があるとき(非常に良い、サブプロダクトになるまで)非常に良いことです。最初のテストを書く前に行う必要があることは、あなたの不変量、最小値や最大値などを特定する必要があるため、ドメインモデル、デプロイメントモデル、および好ましくはクラス図の準備が整うことです。あなたがそれらをテストする前に。設計からユニットテストレベルでこれらを識別できる必要があります。

私の経験ではスヨン、(OOに現実世界のアナロジーをマッピング楽しんでいくつかの著者の経験ではありません:P)、TDDは次のように行く必要があります。

  1. 展開図を作成し、要求仕様から(OFCは、何も石に設定されていない - 今までに)
  2. はこの物語
  3. は様々含めてこの話を(含めるためにあなたのクラス図を作成または変更含めるようにドメインモデルを作成または変更を実装するユーザーストーリーを選択デザインクラス)
  4. テストベクトルを特定する。
  5. 手順4で作成したインターフェイスに基づいてテストを作成します。
  6. テスト(!)をテストします。これは、クラス
  7. テストクラス
  8. 移動を実装し、非常に重要なステップ...
  9. である。これは、開始テストとして完全に大丈夫です、あなたの同僚:)
+5

あなたがこれをやっているなら、あなたはテストドライブ開発をやっていません。あなたはテストを書いていますが、テストケースからデザインを導き出すことはできません。 –

+2

あなたは見ている人の目にそうです:)私が見るように、あなたはあなたのデザインをテストの原因から派生させることはできません。少なくとも効率的ではありません。テストは実装の詳細であり、設計ではありません。再び、私の個人的な視点です。 – cwap

4

でビールを持っています。これにより、期待される動作(動作の仕方)を定義します。あなたが気に入っていたよりもはるかに大きな咬合をしたと感じたら、このテストを一時的に無視して、中途半端な部分的なテストを書くことができます。その後、最初の大きなテストを通過するという目標に向かってあなたを連れて行く他のテスト。赤 - 緑 - 各ステップでリファクタリングします。

小さなテストでは、1つのテストでたくさんのものをテストするべきではないと思います。例えばMethod1()、Method2()、Method3()をDでこれらのパラメータで呼び出すと、コンポーネントD.A、B、Cがstate1、state2、state3になります。 各テストでは、1つだけテストする必要があります。あなたは良いテストの品質のためにSOを検索することができます。ベックの著書からTO-てみ提案(AFAIRとして:

更新「製造オーダーからPartNumbersを取得する」 - それは短く、一つのタスクに焦点を当てているので、しかし、私はあなたのテストは、小規模なテストであることを検討したいです)、あなたは座って、紙の上のSUTのための一行のテストのリストを考え出すかもしれません。これで、自信をつくるために最も簡単なテスト(あなたができると確信しているテスト)を選択できます。またはあなたはあなたが80%自信を持っていることを試みることができますが、道に沿ってSUTについて何かを学ぶのを助けるので、灰色の部分があります。終わりのためにどのように進めるのか分からないものを残しておいてください...うまくいけば、より簡単なものが行われる頃にはもっと分かりやすくなるでしょう。彼らが緑色になると同時に、それらを一つずつ打ちます。

+0

これは私を安堵させ、私はテストを書くために座っています。それを書く方法について考えることさえ、デザインの経験です。私は私のテストに満足しているかどうかは分かりませんが、それは出発点であり、私にいくつかのことを考えさせる原因になります。 – anonymous

+0

これは正確にTDDの最も重要な貢献です。これはクライアントの視点から設計を進め、少なくとも1つのクライアントが必要とする機能を追加するだけです。当初、あなたはコラボレーターを偽造することを選ぶかもしれませんが、それでも彼らの間で最も簡単なインターフェースを築くのに役立ちます - これは大きな勝利です。今後の機能にはいいものはありません。また、リファクタリングを継続することで、シンプルでわかりやすく保守しやすい設計になります。 – Gishu

+0

私は戻って、ベックの本の最初の40〜50ページを読んで、私の最後の読書(数ヶ月前)以来もう少し沈んだものがあります。助けになる2つのことは、a)あなたはテストパスを作るために罪を犯すことができ、b)あなたはただちに緑を一度リファクタリングすることができます。そして、はい、SUTに焦点を当てて考えることが私を助けています、特にSUTが存在する可能性のあるすべての文脈について考えてみましょう。それはより強く脆弱なテストにつながります。 – anonymous