2009-03-04 4 views
1

私はTDDについて読んできましたが、私の次のプロジェクトで使ってみたいと思いますが、この新しいパラダイムでクラスをどのように構築するのかは分かりません。私が使用したい言語はJavaですが、問題は実際には言語固有ではありません。デバイスコミュニケーターのTDD

プロジェクト

私はASCIIオーバーRS232インターフェースが付属してハードウェアのいくつかの作品を持っています。私は簡単なコマンドを発行し、簡単な応答を得ることができ、フロントパネルのようにコントロールすることができます。それぞれの構文はわずかに異なり、非常に異なるコマンドセットを持っています。私の目標は抽象化/インタフェースを作成して、GUIやリモートプロシージャコールを通してそれらをすべて制御できるようにすることです。

問題

私は、最初のステップは、シリアルI/Oのようなすべてのものを実装するための抽象クラスを(私はどのように「コミュニケータ」について、名前で悪いんだ?)を作成することであると信じて、各デバイスのサブクラスを作成します。私はそれがもう少し複雑になると確信していますが、それは私の心の中でアプリケーションの核心です。

ユニットテストでは、実際のハードウェアやシリアル接続が本当に必要ないと思います。私がしたいのは、私のコミュニケータにシリアルポート、ファイル、stdin/stdout、テスト関数からパイプされたInputStreamとOutputStream(またはReaderとWriter)を渡すことです。だから、私はCommunicatorのコンストラクタにそれらを入力として受け取るだけですか?もしそうなら、それをテストフレームワークにすべて設定するのは簡単ですが、実際の人は誰ですか?別のコンストラクタ?コンストラクタを再度呼び出す関数ですか?コミュニケータを正しいI/Oストリームに「接続」することは、別のクラスの担当者ですか?

編集

私は私が求めていたと思った質問への答えを得るために、問題の部分を書き換えることを約あったが、私はそれを考え出したと思います。私は(正確には)2つの異なる機能領域を特定していました。

数ヶ月前に、その出力&生成コマンドを理解するデバイス()との通信シリアルポート

2)への対応

1)が、私は1つのクラスにそれをすべて組み合わせただろう。これを解消するための私の最初のアイデアは、IOストリームだけをデバイスを理解するクラスに渡すことでした。誰がストリームを作成する責任を負っているのか分かりませんでした。

制御の逆転についてより多くの研究を行ったところ、私はと答えました。答えです。問題#1を解決し、問題#2を解決するクラスのコンストラクタ(es?)に渡す別のインターフェイスとクラスを用意してください。そうすれば、両方を別々にテストするのは簡単です。実際のハードウェアに接続し、テストフレームワークが異なることを可能にすることで、#1を達成しました。 #2は#1の模擬試験を受けることでテストすることができます。

これは合理的ですか?より多くの情報を共有する必要がありますか?

+0

テストのビルドと実行にはどのオペレーティングシステムを使用しますか?これは本番で同じですか? –

答えて

2

TDDの場合、は、のようになります。小さなステップで始まり、赤ちゃんのステップでテストを少しずつ成長させてください。

CLARIFIED:具体的なクラスから始めて1つのコマンドを送信し、単体テストをモックまたはスタブでテストします。 (おそらくすべてのオプションではない)十分な場合は、実際のデバイスに対して一度だけテストして、モック/スタブ/シミュレータを検証してください。

最初のコマンドのクラスが操作可能になったら、同じ方法で2番目のコマンドの実装を開始します。最初にモック/スタブをもう一度実行し、確認のためにデバイスに対してもう一度実行します。今では、2つのクラスの類似点が見える場合は、抽象クラスベースのデザインにリファクタリングするか、別のものにリファクタリングすることができます。ガジェットをシミュレートする

少しLinuxの中心であるために申し訳ありません
2

..

私のお気に入りの方法は、彼らの行動をシミュレートするwrite character device driversにあります。これは、シミュレートされたデバイスが異常に動作するようにするioctl()インターフェイスを提供するなど、楽しい機能も提供します。

現時点では、テストから現実世界に至るまで、あなたが実際に開いて読み書きするデバイスだけが重要です。

あなたのガジェットの動作を模倣するのはあまり難しいことではありません。彼らは非常に基本的な指示を受け、非常に基本的な応答を返すように聞こえます。繰り返しますが、単純なioctl()は、シミュレートされたデバイスに誤動作の時間を伝えることができるため、コードがそのようなイベントを適切に処理していることを保証することができます。たとえば、n番目の命令ごとに意図的に失敗します.nはioctl()の呼び出し時にランダムに選択されます。

+0

これは素晴らしいアイデアのように見えますが、今はすべてがWindowsです(ただし、Javaは移植性が高いはずです...)。しかし、これは私が将来のプロジェクトに必要なものかもしれません。あなたはLinuxでドライバを書く上で他の優れたリソースを持っていますか(私はGoogleで見つけられないかもしれません)? –

+0

@drhorrible、Linuxソースツリーにいくつかのサンプルコードがありますが、ドライバの完全なスペクトルは説明していません。キャラクタードライバーの良い例はdrivers/watchdog/softdog.cにあります。これはioctlインターフェースを設定し、/dev/{major}.{minor}に送られた入力を読む方法を示しています。 –

+0

@drhorrible、あります)また、簡単な例の文字ドライバと、USBガジェット用のドライバもあります。それは、ソースツリーの周りを突くことを支払う。 –

1

あなたの編集を見て、私はあなたが正しい方向に向いていると思います。 TDDは、明確な責任を持った小さなクラスで構成されたデザインにあなたを導きます。私もtinkertimのアドバイスをエコーし​​ます。さまざまな方法で動作するように制御でき、 "刺激"できるデバイスシミュレータは、テストにとって非常に貴重です。