質問

TDD について読んでおり、次のプロジェクトにそれを使用したいと考えていますが、この新しいパラダイムでクラスをどのように構成すればよいかわかりません。私が使用したい言語は Java ですが、問題は実際には言語固有ではありません。

プロジェクト

ASCII-over-RS232 インターフェイスを備えたハードウェアがいくつかあります。単純なコマンドを発行し、単純な応答を取得し、フロント パネルから操作するかのように制御できます。それぞれの構文はわずかに異なり、コマンドのセットも大きく異なります。私の目標は、抽象化/インターフェイスを作成して、GUI やリモート プロシージャ コールを通じてそれらをすべて制御できるようにすることです。

問題

最初のステップは、シリアル I/O などのすべてのものを実装するための抽象クラス (名前が苦手です。「Communicator」はどうでしょうか?) を作成し、次にデバイスごとにサブクラスを作成することだと思います。それよりも少し複雑になると思いますが、それが私の頭の中でアプリケーションの核心です。

さて、単体テストの場合、実際のハードウェアやシリアル接続は特に必要ないと思います。私がやりたいのは、シリアルポート、ファイル、stdin/stdout、テスト関数からパイプされたものなどからのものである可能性のあるInputStreamとOutputStream(またはReaderとWriter)をCommunicatorに渡すことです。それでは、Communicator コンストラクターにそれらを入力として受け取らせるだけでよいでしょうか?そうであれば、すべてを設定する責任をテスト フレームワークに置くのは簡単ですが、実際のところ、実際の接続は誰が行うのでしょうか?別のコンストラクター?またコンストラクターを呼び出す関数ですか?Communicator を正しい I/O ストリームに「接続」するのは、別のクラスの誰の仕事ですか?

編集

自分が尋ねていたと思っていた質問に対する答えを得るために、問題のセクションを書き直そうとしていましたが、理解できたと思います。私は (正しく?) 2 つの異なる機能領域を特定しました。

1) シリアルポートの扱い

2) デバイスとの通信 (出力の理解とコマンドの生成)

数か月前なら、すべてを 1 つのクラスにまとめていたでしょう。この状況から脱却するための私の最初のアイデアは、デバイスを理解するクラスに IO ストリームだけを渡すことでしたが、ストリームの作成を誰が担当するのかわかりませんでした。

制御の反転についてさらに研究した結果、 答え。問題 #1 を解決する別のインターフェイスとクラスを用意し、それを問題 #2 を解決するクラスのコンストラクターに渡します。そうすれば、両方を個別にテストするのが簡単になります。#1 は、実際のハードウェアに接続し、テスト フレームワークがさまざまなことを実行できるようにすることです。#2 は、#1 のモックを与えることでテストできます。

これは合理的だと思われますか?さらに情報を共有する必要がありますか?

役に立ちましたか?

解決

TDDを使用する場合は、デザインを浮上させる、小さなステップから始めて、少しずつテストを重ねてクラスを成長させる必要があります。

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

最初のコマンドのクラスが動作可能になったら、同じ方法で2番目のコマンドの実装を開始します。最初に再びモック/スタブを作成し、次に検証のためにデバイスに対して1回実行します。これで、2つのクラスの類似性が見られる場合、抽象クラスベースの設計にリファクタリングすることができます-または別の何かにリファクタリングできます。

他のヒント

少しLinuxを中心としたものでごめんなさい..

ガジェットをシミュレートする私のお気に入りの方法は、キャラクターデバイスドライバーを書く動作をシミュレートします。これにより、シミュレートされたデバイスが異常な動作をするioctl()インターフェースを提供するなどの楽しい機能も得られます。

その時点では、テストから実世界まで、実際にどのデバイスを開いたり、読み書きしたりするかが重要です。

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

あなたの編集内容を見て、あなたはまさに正しい方向に進んでいると思います。TDD は、明確に定義された責任を持つ小さなクラスで構成される設計に向かう傾向があります。私も tinkertim のアドバイスを繰り返します。制御してさまざまな動作を「誘発」できるデバイス シミュレーターは、テストには非常に貴重です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top