0

私はhttpサーバーの新しい実装を扱っています。TCP 接続状態のステートマシンが適切に機能するかどうかを確認するのに役立つ単体テストを作成します。

もちろん、次のような簡単なことを確認する必要があります。サーバーはclosed受信後に状態に切り替わっていますRSTか、それともestablishedシーケンス後に切り替えていますかSYN, SYN+ACK, ACK

このステート マシンで可能なパスの数は非常に多いため、どのテストに焦点を当てるべきかを考えています。

たとえば、Apacheには、パターンを取得できる公開単体テストがありますか?

2 つ目は、アプリケーションの観点からこのテストの作成を開始する必要があるため、単純な Java ソケットを使用してconnectsend、 などのコマンドを使用してシミュレートできるテストの作成に集中する必要があるということです。

4

4 に答える 4

4

何をテストするか

すべての単体テスト戦略の一般的な目標は次のとおりです。

  1. 完全なコード カバレッジ: アプリケーションのコードの各行が、完全なテスト スイート中に少なくとも 1 回実行されることを意味します。
  2. 仕様の完全な網羅: 通常、ソフトウェア開発は、ソフトウェアが何を行い、考えられる各シナリオでどのように反応するかを正確に記述した機能仕様から始まります。仕様に記載されている各要件には、少なくとも 1 つのテストが必要です。仕様がない場合、最小限のテストのガイドラインは、HTTP プロトコル自体の仕様になる可能性があります。

サーバー アプリケーションをテストするときはいつでも、クライアントが HTTP プロトコルの完全な実装であると仮定することはできないことに留意する必要があります。現実の世界では、サーバーは、それを間違って実装したり、アプリケーションの任意の状態で突然終了した信頼性の低い接続を持つクライアントに直面したりします。また、サーバーの脆弱性を意図的に見つけて悪用しようとする悪意のあるクライアントについても説明していません。これらは、テストケースが必要な状況でもあります。

多くの場合、サーバーはマルチスレッドです。つまり、マルチスレッドに伴う通常の問題 (競合状態、デッドロック、同期の問題、ビジー スピンなど) をテストする必要があります。残念ながら、これらの問題は予測が難しく、意味のある単体テストを作成するのはさらに困難です。これらの問題は、通常、単体テストではなく、統合テストとシステム テストの範囲である、さまざまなコンポーネントの相互作用を通じて明らかになるという理由だけではありません。

テスト方法

単体テストは通常​​、外部リソースに依存するべきではありません。依存する場合、独自のアプリケーションではなく、そのリソースをテストしているためです。http サーバーの場合のように、アプリケーションの機能が外部システムに大きく依存している場合は、他のシステムをシミュレートする必要があります。

これは、外部リソースをモック オブジェクトで実装することによって行われます。モック オブジェクトは、外部リソースに依存するオブジェクトの代わりをするオブジェクトです (外部リソースを拡張するか、同じインターフェイスを実装することにより) が、その動作をシミュレートするだけです。Web サーバーのコンテキストでは、Socketを拡張するクラスを作成しますが、実際にネットワークにアクセスせずに外部クライアントをシミュレートするもので Socket のすべてのメソッドをオーバーライドします。

次に、これを使用して、単体テスト中に通常のソケットの代わりにクラスをテストします。

これにより、応答が遅い、非常に速い、または単に間違っているクライアントなど、特別なテスト条件をテストするための特別なモック ソケットを簡単に実装できます。

new Socket()「しかし、テストしたいクラスの内部を作成するとき、これをどのように行うべきか」と疑問に思うかもしれません。答えは、アプリケーションを単体テスト可能にするために、これを行うべきではないということです。キーワードはDependency Injectionです。一言で言えば、依存性注入とは、クラスがnewその種類のクラスの Factory または Builder でない限り、クラスがキーワードを使用してはならないことを意味します。クラスによって使用されるオブジェクトは、それによって作成されるべきではありません。それらは、コンストラクターまたはセッター メソッドを使用して提供する必要があります。

例:

そのためConnectionListener、 を使用してクライアントが接続するのを待機し、クライアントに対して何かを行うクラスがあるServerSocket場合、コンストラクターでその ServerSocket を作成しないでください。その代わりに、ServerSocket を ConnectionListener のコンストラクターに渡す必要があります。製品コードでは、これは通常のサーバー ソケットになります。しかし、単体テストでは、ServerSocket を拡張するモック オブジェクトを渡すことができます。このモック オブジェクトは、1 つ以上のクライアントをシミュレートし、ConnectionListener が期待どおりに動作したかどうかを単体テスト フレームワークに報告します。

于 2013-04-15T00:58:33.113 に答える
3

もちろん、次のような簡単なことを確認する必要があります。RST を受信した後にサーバーがクローズ状態に切り替わるか、またはシーケンス SYN、SYN+ACK、ACK の後に確立状態に切り替わるか。

もちろん違います。これをテストするビジネスはありません。ベンダーの TCP/IP スタックが壊れている場合、世界中ですぐに明らかになります。テストはベンダーの責任です。テストする必要があるのは、独自の新しい HTTP サーバー内の独自のコードです。

于 2013-04-15T01:37:05.750 に答える
2

ステートマシン図を作成することから始めて、個々の状態遷移の数 (有限数であり、おそらく非常に小さい) に基づいてテストを作成します。

于 2013-04-19T18:11:16.593 に答える