Python:ソケットベースのコードのユニットテスト?
質問
使用するPythonクライアント+サーバーを書いています gevent.socket
コミュニケーションのため。コードのソケットレベルの操作をテストする良い方法はありますか(たとえば、無効な証明書とのSSL接続が拒否されることを確認します)?または、それが最も簡単ですか spawn
本当のサーバー?
編集: :複雑な相互作用のために、「ナイーブ」モッキングがSSLコンポーネントをテストするのに十分であるとは思わない。私はそれで間違っていますか?または、SSL'Dをテストするより良い方法はありますか?
解決
サーバーを簡単に起動してから、テストケースでアクセスできます。 Gevent's 独自のテストスイート Geventをテストするために、まさにそれを行います 組み込みサーバー.
例えば:
class SimpleServer(gevent.server.StreamServer):
def handle(self, socket, address):
socket.sendall('hello and goodbye!')
class Test(unittest.TestCase):
def test(self):
server = SimpleServer(('127.0.0.1', 0))
server.start()
client = gevent.socket.create_connection(('127.0.0.1', server.server_port))
response = client.makefile().read()
assert response == 'hello and goodbye!'
server.stop()
使用 0
ポート値の場合、サーバーは利用可能なポートを使用することを意味します。サーバーが開始された後、実際に選択された値は bind
として利用可能です server_port
属性。
StreamServer
SSLもサポートします keyfile
と certfile
コンストラクターへの引数とそれは各ソケットをで包みます SSLObject
ハンドラーに渡す前に。
使用しない場合 StreamServer
そして、あなたのサーバーはに基づいています グリーンレット それから確かに 産卵 それはあなたがすべきことです。忘れないでください 殺す テストケースの最後に。
サーバーを起動してGreenletを産み出すことは、 Gevent, 、新しいスレッドまたはプロセスを作成するよりもはるかに速く、テストケースごとに新しいサーバーを簡単に作成できます。サーバーが必要なくなったらすぐにクリーンアップすることを忘れないでください。
Gevent APIをock笑する必要はないと思います。サーバーやクライアントが同じプロセス内で喜んで生活できるので、それを使用する方がはるかに簡単です。
他のヒント
別の(IMOより良い)方法があります。使用しているライブラリをock笑する必要があります。 Pythonのモッキングヘルパーの例はです Mox.
有効な証明書を備えたサーバーのセットは必要ありません。もう1つは無効な証明書を持つ、SSLサポートがまったくない、パケットにまったく応答しないものなど、「ダミー」クライアントソケットで動作をシミュレートできます。 。 Moxで機能する方法は、最初に期待すべきこととそれがどのように反応するかを「教える」ことです。次に、実際のコードを実行しながら、実際のGevent.socketを模倣したものと交換します。それを手に入れるにはいくつかの練習が必要ですが、それだけの価値があります。
モッキングとスタブは素晴らしいですが、時にはそれを次のレベルの統合に引き上げる必要があります。サーバーを生み出すサーバーを産むことで、時間がかかる可能性があるため、別のテストスイート(統合テストを呼び出す)を検討することができます。
「あなたがそれを使用するようにそれをテストする」は私のガイドラインであり、あなたがあなたのテストが些細なものになるほどock笑とスタブなら、それはそれほど有用ではありません(ほとんどすべてのテストは誰よりも優れています)。悪いSSL証明書の処理を心配している場合は、必ず悪いものを作成し、それらに供給できるテストフィクスチャを書いてください。それがサーバーを産むことを意味する場合、そうです。たぶん、それがあなたに十分な虫であるならば、それはそれを別の方法でテスト可能にするリファクタリングにつながるでしょう。