RESTサーバーに対するRESTクライアントのテスト。フィクスチャーを行うには?


10

単体テストを作成するときは、フィクスチャを使用するのが一般的です。テスト可能なデータが少ないため、次のように言えます。1.すべてのクライアントにWilly Wonkaを含めます。2.クライアント3を削除し、クライアントにWilly Wonkaが含まれないようにします。

単体テストではそれで問題ありません。セットアップ/ティアダウンを使用して、フィクスチャを再ロードするか、トランザクションをロールバックします。したがって、テストの作成、更新、削除はトランザクション内で行われます。新しい一時データは、そのテストの間だけ保持され、その後リセットされます。

しかし、RESTサーバーをRESTクライアントから分離した場合はどうでしょうか。

RESTクライアントが正しく読み取っているだけでなく、正しく作成、更新、削除されていることを確認します。

リモートテストRESTサーバーに対してこれを行う方法の例や提案を見つけることができませんでした

フィクスチャのみを提供するテストRESTサーバーがあるとします。HTTPの完全なステートレスの性質は、「BEGIN TRANSACTION」と「ROLLBACK TRANSACTION」または「RELOAD FIXTURES」タイプのメッセージを送信するのが難しいことを意味しますよね?

私はこれを最初にしたくないので、これについて別の考え方が必要だと感じています。

助言がありますか?


おそらく、それはテストサーバーなので、フィクスチャーをリロードするエンドポイントを持つことができますか?
David Radcliffe

主な問題がテストサーバーを事前定義された状態に戻すことである場合は、「RELOAD TESTDATA」などの特別なテスト関数を残りのAPIに追加して、目的を達成してみませんか?もちろん、そのようなAPI呼び出しが本番環境で利用できないことを確認する必要があります。
Doc Brown

回答:


7

ソフトウェアシステムは、理想的には明確に定義されたシステム境界とシステム間のインターフェイスを備えています。RESTサービスはこの良い例です。

そのために、私は推薦に対して、あなたが何をしようとしてやって。

具体的には:

RESTクライアントが正しく読み取っているだけでなく、正しく作成、更新、削除されていることを確認します。

代わりに私が提案するのは:

  • RESTクライアントのテストを作成し、特定の入力と出力が与えられたときに正しく動作することを確認します。良い値(期待される値)と悪い値(予期されない値)を考慮します。

  • RESTサービス(ユーザーが制御している場合)のテストを作成し、意図した機能に従って動作する

  • テストを問題の領域に近づけて、そのコンテキストで重要なことの設計と開発をガイドできるようにします。


3
ここでは、統合テストのアイデア全体を何気なく却下します。このアプローチは実践から得られたものではないと思います。
2013年

すべての役立つ提案に感謝します。また、Twitterから、Ruby gemの「webmock」を試してREST APIサーバーの応答を模擬するという素晴らしい提案を受けました。また、私が説明しているのは統合テストのように見えるという "febeling"にも同意します。そのため、個別に調査します。再びありがとうございました。-デレク
2013年

APIをモックすることは、問題を解決する優れた方法です。しかし、モックAPI ==実際のAPIであることをどのように確認しますか?
FrEaKmAn 2015年

4

ここで覚えておくべき2つの角度:

  • コードまたは配管をテストしていますか?よく知られているサービスとクライアントスタックを使用していると想定すれば、おそらくテスターを安全に推定できます。何千ものユーザーが、基盤に根本的なバグがないことを確認します。
  • テストがべき等でないのはなぜですか?非本番データを書き込む方法、または別のエンドポイントに書き込む方法を作成します。予測可能な命名パターンをいくつか選択してください。テストの前に、残りのサーバーDBをプリロードします。そして、これを実現する方法はおそらくいくつかあります-メソッドは本当に戦術的であり、アプリの性質に依存する必要があります。

2

RESTサーバーの応答を偽造することがクライアントをテストする最良の方法だと思います。

Rubyの場合、FakeWeb gemを使用して偽の応答を発行できます-https ://github.com/chrisk/fakeweb

また、JavaScriptでは、Sinon.JSのようなものを使用できます。これにより、偽のサーバー(http://sinonjs.org/docs/#fakeServer)が提供されます。


1

他の人が言ったように、クライアントをテストしている場合、サーバー上で作成、削除などする必要はありません。多くの場合、サーバーをモックする必要すらありません。Ruby、Python、PHPのいずれで書かれているかにかかわらず、正しい要求を行い、応答を正しく処理していることを確認するだけで十分です。ある時点で、クライアントはおそらくHTTPライブラリのメソッドを使用して、リクエストと、そのメソッドをモックし、その呼び出し方法を確認して、テスト結果を返すだけで十分です。

urllib2リクエストを作成するために使用する架空のPythonクライアントを取り上げます。あなたはおそらくクライアントにいくつかのメソッドを持っています、それを呼び出しましょうget()、それは中に呼び出しがありますurllib2.Request()。あなたは本当にあなた自身のクラスのへの呼び出しを模擬する必要があるだけget()です。

@patch('your.Client.get')
def test_with_mock(self, your_mock):
    your_mock.return_value({'some': 'json'})
    test_obj = your.Client.get_object(5)
    your_mock.assert_called_with('/the/correct/endpoint/5')

この非常に簡略化された例では、PythonのMockライブラリを使用して、いくつかのAPIから何かを取得するための正しいURLを生成your.Clientするget_object()メソッドで仮想クラスをテストします。リクエストを行うために、クライアントはそのget()URLでそのメソッドを呼び出します。ここで、そのメソッドはモック化され(your.Client.get「パッチ」されての制御下にありますyour_mock)、テストは正しいエンドポイントが要求されたかどうかをチェックします。

モックされたメソッドは、your_mock.return_valueクライアントが処理する必要のある構成済みのJSON応答()を返します。さらにアサーションを作成して、予期した方法で期待したデータを処理したことをテストします。


しかし、「正しい」要求を行っているときに、それが実際の正しい(本番環境での)要求であることをどのように確信していますか?私があなたの提案を理解していれば、APIが変更または中断しても、テストは引き続き機能します。制作中はまったく別の話になります。
FrEaKmAn 2015年

1

あなたが説明するのは、統合テストのシナリオです。これらは通常、セットアップと破棄が少し厄介です。実行が遅くなり、非常に壊れやすくなります。

フィクスチャを使用したアプローチは、ぎこちなく不器用ですが、一部のフレームワーク(Railsなど)のデフォルトの方法であり、すでにサポートされています。フィクスチャを使用してデータベースを準備するには、抽象的なテストケースなどが必要です。(Railsでのテストカテゴリの異常な命名に注意してください。DBフィクスチャを使用した単体テストは、厳密に言えば統合テストでもあります。)

私があなたのシナリオに取り組む方法は、APIアプリケーションの状態またはそのデータベースに対するテスト固有の制御を受け入れることです。テスト環境にのみ存在する、セットアップとティアダウンのための追加のエンドポイントを持つことができます。または、アプリケーション/ APIの背後でデータベース(または使用しているもの)と通信します。

これが(過度の意味で)多すぎると感じた場合は、データベースのフィクスチャを使用するアプローチがそれを実行することを検討してください。追加のテスト固有の手段を使用してデータベースまたはアプリケーションの状態を操作します。

ただし、この議論はHTTPのステートレスな性質とは関係がないと思います。HTTPはステートレスですが、ほとんどの場合、アプリケーションは間違いなくステートレスです。RESTの厳格さを探しているあなたに少し似ているようです。すべてのリソースを完全に作成、読み取り、削除できるようにすることもできます。その場合、通常のAPI手段を使用してすべてのセットアップとティアダウンを実行できます。ただし、これは実際には行われないことがよくあります。これは、少なくともテスト環境の外ではなく、アプリケーションのビジネス理解からの特定の操作を含めたくないためです。


1

モンキーパッチ

私の仕事では、既存のxUnitフレームワークとクライアントとサーバー間のモンキーパッチネットワークコールを使用してATDDを行っています。同じプロセススペースでクライアントをロードし、モンキーはRESTスタックコードの先頭にネットワーク呼び出しをパッチします。その後、すべての呼び出しは通常どおりにクライアントから発行され、サーバーコードは通常表示されるとおりに要求を取得します。

利点

  • サーバーの起動と同期する必要がない(サーバーがないため)
  • 古典的なユニットのセットアップと分解方法を活用して、器具などを管理します
  • テストをより細かく制御するためにモック/スタブおよびその他のサルのパッチを使用する機能
  • xUnitフレームワークを使用して記述できます

トレードオフ

  • マルチプロセスの相互作用/問題(ロック、リソース不足など)を公開しない
  • マルチサーバーの問題(データのシリアル化、クラスタリングスタイル)を公開していません
  • シミュレートされているため(ネットワークアクセス、タイムアウトエラーなど)、ネットワークの問題は発生しません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.