SSO アプリケーションの統合テストは、分散アプリケーションのテストという、より一般的な問題の特殊なケースです。これは難しい問題であり、特効薬はないようです。一連の異なるサーバーまたはサービスを組み合わせて全体としてテストするには、さまざまな方法があります。両極端は
a) システム全体のインスタンスをテストします。その場合、モックやスタブは必要ありませんが、スタック全体の完全で本格的なセットアップが必要です。これには、関連するすべてのサーバーの実行中のインスタンスが含まれます。各テストでは、アプリケーション スタック全体をセットアップし、スタック全体をテストします。つまり、関連するすべてのコンポーネントを含む分散システム全体を全体としてテストしますが、これは一般的には困難です。この全体が機能するのは、各コンポーネントとすべての接続が正常に機能している場合のみです。
b) 各コンポーネントの統合テストを作成し、それをブラック ボックスとして扱い、不足している接続をモックとスタブでカバーします。実際には、このアプローチは単体テストでより一般的であり、モデル、ビュー、およびコントローラー (多くの場合、ビューとコントローラーは一緒に) の各 MVC レイヤーに対してテストを記述します。
どちらの場合も、接続の切断は考慮されていません。原則として、外部サーバー/サービスごとに次の可能性を確認する必要があります
- ダウンしています
- 正常に動作しています
- が起動していて、返信が間違っている
- はアップしていますが、間違ったデータを送信しています
基本的に、分散アプリのテストは難しいです。これが、分散アプリケーションの開発が難しい理由の 1 つです。分散アプリケーションのパーツとサーバーが増えるほど、本番環境、ステージング環境、テスト環境、開発環境など、多くの本格的な環境をセットアップすることが難しくなります。システムが大規模になるほど、統合テストは難しくなります。実際には、最初のアプローチを使用して、アプリケーション全体の小さいながらも完全なバージョンを作成します。典型的な単純なセットアップは、アプリケーション サーバー + DB サーバー + 検索サーバーです。開発マシンには、完全なシステムの 2 つの異なるバージョンがあります。
- 複数のデータベースを持つ 1 つの DB サーバー (開発およびテスト)
- 複数のインデックスを持つ 1 つの検索サーバー (開発およびテスト)
検索サーバー用の一般的な Ruby プラグイン (Sphinx 用の Thinking Sphinx または Solr 用の Sunspot) は、キュウリと統合テストをサポートしています。テストの特定の部分で検索サーバーを「オン」にします。検索サーバーを使用しないコードの場合、サーバーを「スタブ」するか、接続をモックアウトして、不要なインデックス作成を回避します。
RSpec テストの場合、認証方法をスタブ化することができます。たとえば、コントローラー テストの場合は、
before :each do
@current_user = Factory(:user)
controller.stub!(:current_user).and_return(@current_user)
controller.stub!(:logged_in?).and_return(:true)
end
ヘルパーとビューのテストでも機能しますが、RSpec リクエストまたは統合テストでは機能しません。
キュウリ テストの場合、検索サーバーへの接続をスタブに置き換えることで検索サーバーをスタブ化できます (Sunspot と Solrの場合、Solr への接続をカプセル化するSunspot.session を置き換えることでこれを行うことができます)。
これはすべてうまくいくように思えますが、残念ながら、このソリューションを SSO サーバーに転送するのは少し難しいです。一般的な最小構成は、アプリケーション サーバー + DB サーバー + SSO サーバーです。完全な統合テストでは、1 つの SSO サーバーに複数のユーザー データ ストア (開発およびテスト) をセットアップする必要があります。SSO サーバーをセットアップするだけでも十分に困難です。複数のユーザー データ ストアを使用して SSO サーバーをセットアップすることは、おそらくあまり良い考えではありません。
この問題に対する 1 つの考えられる解決策は、おそらくFakewebの方向のどこかにあるでしょう。FakeWeb は、Web リクエストを偽造するために Blaine Cook によって作成された Ruby ライブラリです。これにより、テスト環境をライブ サービスから切り離すことができます。残念ながら、SSO サーバーの応答を偽装するのは少し困難です。
私が最終的に使用した別の可能な解決策は、偽のログインを使用することです。つまり、統合テスト内で呼び出すことができる偽のログインメソッドを追加します。この偽のログインは、テスト中にのみ追加される動的な方法です (モンキー パッチの形式を介して)。これは少し面倒ですが、うまくいくようです。